【发布时间】:2016-04-03 12:15:57
【问题描述】:
我使用了过去 kaggle 挑战赛中的数据,这些数据基于多家商店的面板数据,时间跨度为 2.5 年。每个观察都包括给定商店日期的客户数量。对于每个商店日期,我的目标是计算过去 60 天内访问该商店的平均顾客数量。
下面是完全符合我需要的代码。但是,它会永远存在 - 处理 c.800k 行需要一个晚上。我正在寻找一种聪明的方法来更快地实现相同的目标。
我已经包含了对初始数据集的 5 个观察结果以及相关变量:商店 ID(商店)、日期和客户数量(“客户”)。
注意:
- 对于迭代中的每一行,我最终使用 .loc 而不是例如row["Lagged No of customers"] 因为“row”没有在单元格中写入任何内容。我想知道为什么会这样。
- 我通常使用“应用,轴 = 1”填充新列,因此我非常感谢任何基于此的解决方案。我发现当对于每一行,使用同一行级别的值跨列进行计算时,“应用”工作正常。但是,我不知道“应用”函数如何涉及不同的行,而这正是这个问题所需要的。到目前为止,我看到的唯一例外是“diff”,它在这里没有用处。
谢谢。
样本数据:
pd.DataFrame({
'Store': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1},
'Customers': {0: 668, 1: 578, 2: 619, 3: 635, 4: 785},
'Date': {
0: pd.Timestamp('2013-01-02 00:00:00'),
1: pd.Timestamp('2013-01-03 00:00:00'),
2: pd.Timestamp('2013-01-04 00:00:00'),
3: pd.Timestamp('2013-01-05 00:00:00'),
4: pd.Timestamp('2013-01-07 00:00:00')
}
})
有效但速度极慢的代码:
import pandas as pd
import numpy as np
data = pd.read_csv("Rossman - no of cust/dataset.csv")
data.Date = pd.to_datetime(data.Date)
data.Customers = data.Customers.astype(int)
for index, row in data.iterrows():
d = row["Date"]
store = row["Store"]
time_condition = (d - data["Date"]<np.timedelta64(60, 'D')) & (d > data["Date"])
sub_df = data.loc[ time_condition & (data["Store"] == store), :]
data.loc[ (data["Date"]==d) & (data["Store"] == store), "Lagged No customers"] = sub_df["Customers"].sum()
data.loc[ (data["Date"]==d) & (data["Store"] == store), "No of days"] = len(sub_df["Customers"])
if len(sub_df["Customers"]) > 0:
data.loc[ (data["Date"]==d) & (data["Store"] == store), "Av No of customers"] = int(sub_df["Customers"].sum()/len(sub_df["Customers"]))
【问题讨论】:
-
为什么要取
data的前100行? (data[:100]) -
@Alexander
time_condition只是一个选择正确时间窗口的掩码,随后用于创建 sub_df; @David Z 我需要 100 行而不是整晚等待输出,但目标是获得整个数据集的输出 -
在这种情况下,我认为最好将
[:100]排除在您问题的代码示例之外。毕竟,您的示例代码应该说明您遇到的问题 - 在这种情况下,太慢了。这没什么大不了的,但是如果您发现自己因为其他原因再次编辑,不妨考虑将其删除。 -
@DavidZ 刚刚更新