Car Shopping Solution¶
all_fair_prices = fair_prices.loc[asking_prices.index] off_market_prices = asking_prices - all_fair_prices below_fair_prices = (off_market_prices < 0).reset_index(drop=True) below_fair_prices.loc[below_fair_prices].index.to_list() # [0, 4]
Your first instinct may be to do
asking_prices - fair_prices. In fact, Pandas uses the index labels to subtract
fair_prices from each
# camry 1500 # civic -500 # civic 2100 # mustang 1000 # mustang -500 # dtype: int64
Unfortunately the resulting Series gets reordered by the index in alphabetical order, so we lose track of which (asking price, fair price) is represented by each row.
An alternative strategy is, "for each asking price, get the corresponding fair price". We can accomplish this with
fair_prices.loc passing in the index labels from
asking_prices. We'll store the result in a variable
all_fair_prices = fair_prices.loc[asking_prices.index] print(all_fair_prices) # civic 5500 # civic 5500 # camry 7500 # mustang 7500 # mustang 7500 # dtype: int64
Next, we calculate how far off each fair price is from the asking price.
off_market_prices = asking_prices - all_fair_prices print(off_market_prices) civic -500 civic 2100 camry 1500 mustang 1000 mustang -500 dtype: int64
The good deals are the negative values in this Series.
Next we set
below_fair_prices = off_market_prices < 0 to get a boolean series indicating
whether each car for sale is below its fair price.
below_fair_prices = off_market_prices < 0 below_fair_prices # civic True # civic False # camry False # mustang False # mustang True # dtype: bool
We'll also chain that with
.reset_index(drop=True) to make the index a RangeIndex like
[0, 1, 2, 3, 4].
below_fair_prices = (off_market_prices < 0).reset_index(drop=True) below_fair_prices # 0 True # 1 False # 2 False # 3 False # 4 True # dtype: bool
Now our goal is to pick out the indices corresponding to True values - in this case 0 and 4.
If we do
below_fair_prices.loc[below_fair_prices], we'll get back the subseries with just True elements.
below_fair_prices.loc[below_fair_prices] # 0 True # 4 True # dtype: bool
and then we can chain that with
.index.to_list() to get back the index values in list.
below_fair_prices.loc[below_fair_prices].index.to_list() # [0, 4]