I have a piece of pandas code which used to work in version 1.0.5. Here's a simplified, self-contained example of my problem:
import pandas as pd
df = pd.DataFrame(data=[
('bk1', 10),
('bk1', None),
('bk1', 13),
('bk1', None),
('bk2', None),
('bk2', 14),
('bk3', 12),
('bk3', None),
], columns=('book', 'price'))
grouped = df.groupby(['book'], as_index=False, sort=False)
df = grouped.fillna(method='ffill')
print(df)
In this example, we have a list of book sales, where some of the prices are missing. We're trying to fill in the missing data by using the previous row, where that row is the same book.
In Pandas 1.0.5, this produces a dataframe with two columns:
book price
0 bk1 10.0
1 bk1 10.0
2 bk1 13.0
3 bk1 13.0
4 bk2 NaN
5 bk2 14.0
6 bk3 12.0
7 bk3 12.0
In Pandas 1.1.0, this removes the book column, which makes the output unusable.
price
0 10.0
1 10.0
2 13.0
3 13.0
4 NaN
5 14.0
6 12.0
7 12.0
I have read the patch notes for version 1.1.0, and I can't find any remarks about this change.
Questions:
- Is this a bug in Pandas, or am I relying on undefined behavior?
- Is there a more natural way to express this?
Questions you might ask:
Why not use fillna without a groupby?
In this example, the first row with bk2 has no price, but it wouldn't make any sense to fill it in with the previous row, which is the price of bk1.
Why use ffill instead of dropping NA values?
My real code is working with timeseries data, and ffill is the most natural way to express carrying forward the last known observation.