我有包含以下信息的数据:产品编号为i
,产品上市时间为t
,商家ID 作为m
和价格。对于每种产品i
,都有一个列出时间t
的清单,在该清单上我为所有商人m
定价。
当特定商人m
在i
处没有t
的要约时,(i,t,m)
的条目就会丢失。
我想要一个价格为零的条目,以表示该商人目前没有报价。
请注意,每种产品的商家是分开的:我想为在此产品上出现过的商家添加条目,而不是为所有出现在该产品上的商家添加条目任何产品。
以下代码达到了我想要的结果:
def addMissingMerchants(pDF):
return pDF.set_index(['i','t','m']).unstack('m').fillna(0).stack('m').reset_index();
df = df.groupby('i').progress_apply(addMissingMerchants).drop('i',axis=1).reset_index().drop('level_1',axis=1);
但是,这段代码很慢:它在我的系统上每秒处理大约15种产品。
有什么方法可以更快地达到相同的结果?
最小工作示例:
i t m p
40181 3996 2018-08-26 02:33:45 162082 67.90
40182 3996 2018-08-26 03:14:10 162082 67.90
40194 3996 2018-08-26 02:33:45 193879 58.00
40195 3996 2018-08-26 03:14:10 193879 58.00
40210 3996 2018-08-26 03:14:10 256684 57.98
40226 3996 2018-08-26 02:33:45 373084 58.00
40227 3996 2018-08-26 03:14:10 373084 58.00
40247 3996 2018-08-26 02:33:45 1238707 53.98
40248 3996 2018-08-26 03:14:10 1238707 53.98
所需的输出:
i t m p
0 3996 2018-08-26 02:33:45 162082 67.90
1 3996 2018-08-26 02:33:45 193879 58.00
2 3996 2018-08-26 02:33:45 256684 0.00
3 3996 2018-08-26 02:33:45 373084 58.00
4 3996 2018-08-26 02:33:45 1238707 53.98
5 3996 2018-08-26 03:14:10 162082 67.90
6 3996 2018-08-26 03:14:10 193879 58.00
7 3996 2018-08-26 03:14:10 256684 57.98
8 3996 2018-08-26 03:14:10 373084 58.00
9 3996 2018-08-26 03:14:10 1238707 53.98
(请注意以2开头的新行)
当前时间成本:
%%timeit
addMissingMerchants(df)
100 loops, best of 3: 7.59 ms per loop
答案 0 :(得分:0)
与其重新组织和重新堆叠,不如对整个数据框重新编制索引。首先建立一个元组列表:
tuples = [];
for i, productData in df.groupby('i'):
tList = productData.t.unique();
for m in productData.m.unique():
tuples.extend([(i,m,t) for t in tList]);
然后使用元组为数据框重新编制索引:
df = df.set_index(['i','m','t'])
df = df[~df.index.duplicated(keep='first')]
idx = pd.MultiIndex.from_tuples(tuples,names=['i','m','t'])
df = df.reindex(idx,fill_value=0).reset_index()
这需要花费几分钟才能完成整个数据帧,这比groupby-unstack-restack解决方案(大约需要1.5h)要好得多。