当前运行约220K行需要40至50分钟
shop timestamp flag
10061 1577525275 NaN
10061 1577534732 NaN
10061 1577741715 NaN
10061 1577741800 NaN
10084 1577405286 NaN
def foo(row):
criteria = (pd.isnull(df2.flag)) & (df.shop==row.shop) & (abs(df.timestamp-row.timestamp) <= 3600)
df2.loc[criteria, 'flag'] = 1
df2 = df.copy()
df2.apply(foo, axis=1)
我正在做的是df2中的每一行,我正在对照主df进行检查,看看是否在同一家商店中,在小时内还有哪些其他行具有时间戳,并将标志设置为1。 numpy向量使运行速度更快的方法?
预期输出:
shop timestamp flag
10061 1577525275 NaN
10061 1577534732 NaN
10061 1577741715 1
10061 1577741800 1
10084 1577405286 NaN
答案 0 :(得分:1)
要更快地完成任务,请定义以下功能:
def newFlag(grp):
tt = grp.timestamp
ind = np.nonzero(np.triu(np.absolute(tt[np.newaxis, :] - tt[:, np.newaxis]) <= 3600, 1))
tbl = grp.flag.values
tbl[np.concatenate(ind)] = 1
return pd.Series(np.where(np.isnan(grp.flag), tbl, grp.flag), index=grp.index)
然后应用它,将结果保存在 flag 列中:
df['flag'] = df.groupby('shop').apply(newFlag).reset_index(level=0, drop=True)
此解决方案的速度基于 shop 的分组,因此您不必 比较有关不同商店的行。
另一个与速度有关的重要因素是使用 Numpy 函数, 它的运行速度比 Pandas 快得多。
要完全理解所有详细信息,请为选定的组逐步运行此代码 行(针对特定的 shop ),然后查看结果。
答案 1 :(得分:0)
您需要按商店对数据框进行分组,然后按时间戳对每个组进行排序,最后只检查上一行和下一行:
print(df)
shop timestamp
0 10061 1577525275
1 10061 1577534732
2 10061 1577741715
3 10061 1577741800
4 10084 1577405286
def have_similar(df):
df = df.sort_values('timestamp')
df = df.assign(
flag = (df.timestamp - df.timestamp.shift(1) < 3600) |
(df.timestamp.shift(-1) - df.timestamp < 3600)
)
return df
result = df.groupby('shop').apply(have_similar).reset_index(drop=True)
print(result)
shop timestamp flag
0 10061 1577525275 False
1 10061 1577534732 False
2 10061 1577741715 True
3 10061 1577741800 True
4 10084 1577405286 False