使用三重索引填充数据框中的日期
Filling dates in dataframe with triple index
我知道有人提出了与此问题类似的问题,但当您只有一个分类变量时,该解决方案有效。我有两个,MultiIndexes
对我来说一直很难处理。问题是,我有以下数据框:
Date Product eCommerce Sales
12-10-2018 A 1 10
12-12-2018 A 0 7
12-13-2018 A 1 4
12-15-2018 A 1 2
12-15-2018 A 0 2
12-11-2018 B 1 8
12-13-2018 B 1 6
所以我需要了解每个日期有无电子商务的销售额,并用零销售额填写未出现的日期。我想要的输出是:
Date Product eCommerce Sales
12-10-2018 A 1 10
12-11-2018 A 1 0
12-12-2018 A 1 0
12-13-2018 A 1 4
12-14-2018 A 1 0
12-15-2018 A 1 2
12-12-2018 A 0 7
12-13-2018 A 0 0
12-14-2018 A 0 0
12-15-2018 A 0 2
12-11-2018 B 1 8
12-12-2018 B 1 0
12-13-2018 B 1 6
注意:它只是一个DataFrame,我只是添加了空格来区分索引。
因此在原始 DataFrame 中,产品 A 的电子商务销售缺少 12-11 和 12-14,产品 A 的非电子商务销售缺少 12-13 和 12-14,而 12-12缺少产品 B 的电子商务销售
事实是,我设法实现了我想要的,通过一个非常低效的循环,大约需要 25 分钟 运行:
df_full= pd.DataFrame(columns=df.columns)
for sku in df['Product'].unique():
aux=df.loc[df['Product']==sku]
dates= pd.DataFrame(pd.date_range(start=aux.Date.min(), end=aux.Date.max(),freq='D'),columns=['Date'])
df3 = df.loc[df['id_prod']==sku].merge(dates,
how='outer',left_on='Date',
right_on='Date').sort_values(by='Date')
df3.fillna(method='ffill',inplace=True)
df_full= df_full.append(df3)
我非常有信心我可以用矢量化的方式做到这一点,这应该会花费更少的时间(我有 290 个可能日期的 2,300 个产品)。你知道我怎样才能做到这一点吗?
编辑:添加了粗体文本以更好地解释问题
使用单个 DatetimeIndex
,然后使用 groupby
+ resample.asfreq()
(可以对数字列使用总和),因为日期范围取决于组。
import pandas as pd
df['Date'] = pd.to_datetime(df.Date)
df = df.set_index('Date')
df.groupby(['Product', 'eCommerce'], sort=False).Sales.resample('D').sum().reset_index()
如果您有很多列要用零填充,那么:
(df.groupby(['Product', 'eCommerce'], sort=False)
.resample('D').sum()
.drop(columns=['Product', 'eCommerce'])
.reset_index())
输出:
Product eCommerce Date Sales
0 A 1 2018-12-10 10
1 A 1 2018-12-11 0
2 A 1 2018-12-12 0
3 A 1 2018-12-13 4
4 A 1 2018-12-14 0
5 A 1 2018-12-15 2
6 A 0 2018-12-12 7
7 A 0 2018-12-13 0
8 A 0 2018-12-14 0
9 A 0 2018-12-15 2
10 B 1 2018-12-11 8
11 B 1 2018-12-12 0
12 B 1 2018-12-13 6
我知道有人提出了与此问题类似的问题,但当您只有一个分类变量时,该解决方案有效。我有两个,MultiIndexes
对我来说一直很难处理。问题是,我有以下数据框:
Date Product eCommerce Sales
12-10-2018 A 1 10
12-12-2018 A 0 7
12-13-2018 A 1 4
12-15-2018 A 1 2
12-15-2018 A 0 2
12-11-2018 B 1 8
12-13-2018 B 1 6
所以我需要了解每个日期有无电子商务的销售额,并用零销售额填写未出现的日期。我想要的输出是:
Date Product eCommerce Sales
12-10-2018 A 1 10
12-11-2018 A 1 0
12-12-2018 A 1 0
12-13-2018 A 1 4
12-14-2018 A 1 0
12-15-2018 A 1 2
12-12-2018 A 0 7
12-13-2018 A 0 0
12-14-2018 A 0 0
12-15-2018 A 0 2
12-11-2018 B 1 8
12-12-2018 B 1 0
12-13-2018 B 1 6
注意:它只是一个DataFrame,我只是添加了空格来区分索引。
因此在原始 DataFrame 中,产品 A 的电子商务销售缺少 12-11 和 12-14,产品 A 的非电子商务销售缺少 12-13 和 12-14,而 12-12缺少产品 B 的电子商务销售
事实是,我设法实现了我想要的,通过一个非常低效的循环,大约需要 25 分钟 运行:
df_full= pd.DataFrame(columns=df.columns)
for sku in df['Product'].unique():
aux=df.loc[df['Product']==sku]
dates= pd.DataFrame(pd.date_range(start=aux.Date.min(), end=aux.Date.max(),freq='D'),columns=['Date'])
df3 = df.loc[df['id_prod']==sku].merge(dates,
how='outer',left_on='Date',
right_on='Date').sort_values(by='Date')
df3.fillna(method='ffill',inplace=True)
df_full= df_full.append(df3)
我非常有信心我可以用矢量化的方式做到这一点,这应该会花费更少的时间(我有 290 个可能日期的 2,300 个产品)。你知道我怎样才能做到这一点吗?
编辑:添加了粗体文本以更好地解释问题
使用单个 DatetimeIndex
,然后使用 groupby
+ resample.asfreq()
(可以对数字列使用总和),因为日期范围取决于组。
import pandas as pd
df['Date'] = pd.to_datetime(df.Date)
df = df.set_index('Date')
df.groupby(['Product', 'eCommerce'], sort=False).Sales.resample('D').sum().reset_index()
如果您有很多列要用零填充,那么:
(df.groupby(['Product', 'eCommerce'], sort=False)
.resample('D').sum()
.drop(columns=['Product', 'eCommerce'])
.reset_index())
输出:
Product eCommerce Date Sales
0 A 1 2018-12-10 10
1 A 1 2018-12-11 0
2 A 1 2018-12-12 0
3 A 1 2018-12-13 4
4 A 1 2018-12-14 0
5 A 1 2018-12-15 2
6 A 0 2018-12-12 7
7 A 0 2018-12-13 0
8 A 0 2018-12-14 0
9 A 0 2018-12-15 2
10 B 1 2018-12-11 8
11 B 1 2018-12-12 0
12 B 1 2018-12-13 6