Product price on a given date, defaulting to 10 before any change
products(product_id, new_price, change_date) logs each price change. Find every product's price as of 2019-08-16: the new_price from its latest change on or before that date, or 10 if it had no change by then. Return product_id, price.
import pandas as pd
def price_on_date(products: pd.DataFrame) -> pd.DataFrame:
# your code here
Write the implementation.
This is a point-in-time lookup. Keep changes on or before the target date, take each product's latest such change (max change_date, e.g. via idxmax after sorting or groupby), and read its new_price. Then reindex against all product ids and fill missing prices with 10 for products with no change by the date.
- ✗Taking the latest change ignoring the target date
- ✗Defaulting only products with zero rows, not zero pre-date changes
- ✗Averaging prices instead of an as-of lookup
- →Why filter by date before taking the latest change?
- →How would you extend this to an arbitrary query date column?
Restrict to changes on or before the date, take each product's latest one, then fill the default for products with none.
import pandas as pd
def price_on_date(products: pd.DataFrame) -> pd.DataFrame:
cutoff = pd.Timestamp('2019-08-16')
before = products[products['change_date'] <= cutoff]
latest = before.loc[before.groupby('product_id')['change_date'].idxmax()]
result = latest[['product_id', 'new_price']].rename(
columns={'new_price': 'price'})
all_ids = pd.DataFrame({'product_id': products['product_id'].unique()})
return all_ids.merge(result, on='product_id', how='left').fillna({'price': 10})
A product whose only change is after the cutoff (or which never changed) is absent from before, so the left merge leaves its price null and fillna(10) applies the pre-change default. idxmax on change_date per product is the as-of pick.