嗨,我有一个如下所示的数据框
Cust_ID created_date tran_date Sales_Value Quantity_Sold
0 1 2021-01-31 2021-01-31 126 12
1 1 2021-01-31 2021-03-31 5 3
2 1 2021-01-31 2021-06-30 20 5
3 2 2020-12-31 2021-02-28 200 5
4 2 2020-12-31 2021-03-31 250 25
我需要为每个 customer_ID 填充从创建日期到当前月份的缺失月份。基本上对于每个客户,自客户创建日期到当前日期,我应该每个月/每年有一行 因此,如果当前月份是 07/2021,则数据框应如下所示
Cust_ID created_date tran_date Sales_Value Quantity_Sold
0 1 2021-01-31 2021-01-31 126 12
1 1 2021-01-31 2021-02-28 0 0
2 1 2021-01-31 2021-03-31 5 3
3 1 2021-01-31 2021-04-30 0 0
4 1 2021-01-31 2021-05-31 0 0
5 1 2021-01-31 2021-06-30 20 5
6 1 2021-01-31 2021-07-31 0 0
7 2 2020-12-31 2020-12-31 0 0
8 2 2020-12-31 2021-01-31 0 0
9 2 2020-12-31 2021-02-28 200 5
10 2 2020-12-31 2021-03-31 250 25
11 2 2020-12-31 2021-04-30 0 0
12 2 2020-12-31 2021-05-31 0 0
13 2 2020-12-31 2021-06-30 0 0
14 2 2020-12-31 2021-07-31 0 0
实现这一目标的最佳方法是什么?
最佳答案
使用GroupBy.apply
具有自定义功能 DataFrame.reindex
和 period_range
将 tran_date
转换为月份:
df['created_date'] = pd.to_datetime(df['created_date'])
df['tran_date'] = pd.to_datetime(df['tran_date']).dt.to_period('m')
now = pd.to_datetime('now')
print (now)
f = lambda x: x.reindex(pd.period_range(x.name[1], now, freq='M', name='tran_date'),
fill_value=0)
df = (df.set_index('tran_date')
.groupby(['Cust_ID', 'created_date'])[['Sales_Value', 'Quantity_Sold']]
.apply(f)
.reset_index()
)
df['tran_date'] = df['tran_date'].dt.to_timestamp(how='end').dt.normalize()
print (df)
Cust_ID created_date tran_date Sales_Value Quantity_Sold
0 1 2021-01-31 2021-01-31 126 12
1 1 2021-01-31 2021-02-28 0 0
2 1 2021-01-31 2021-03-31 5 3
3 1 2021-01-31 2021-04-30 0 0
4 1 2021-01-31 2021-05-31 0 0
5 1 2021-01-31 2021-06-30 20 5
6 1 2021-01-31 2021-07-31 0 0
7 2 2020-12-31 2020-12-31 0 0
8 2 2020-12-31 2021-01-31 0 0
9 2 2020-12-31 2021-02-28 200 5
10 2 2020-12-31 2021-03-31 250 25
11 2 2020-12-31 2021-04-30 0 0
12 2 2020-12-31 2021-05-31 0 0
13 2 2020-12-31 2021-06-30 0 0
14 2 2020-12-31 2021-07-31 0 0
关于python - Pandas DataFrame - 添加缺失月份的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68361047/