首页 > 解决方案 > 在熊猫df的滚动窗口中计算重复行

问题描述

我有一个带有混合 str/float 列的大型 pd.DataFrame。我想在一行的(中心)20 分钟窗口内计算该行的重复次数。

例如:

time = [3,4,5,6,10,15,25,27,50]
a = np.ones(len(time))
b = np.zeros(len(time))
c = ['a', 'a', 'b', 'b', 'b', 'c', 'd','d','d']

df = pd.DataFrame({'time':time, 'a':a, 'b':b, 'c':c})

我期望的结果是:

result = [1,1,2,2,2,0,1,1,0]

如您所见,结果与时间长度相同,它计算该行两侧 10 分钟内的重复次数。例如,time=27 的行只有一个重复项,因为虽然 time=50 的行是重复项,但时间太远了,无法考虑。

获得结果的一种非常缓慢和丑陋的方法是使用 for 循环并手动创建一个移动的窗口:

result = []

for i, t in zip(df.index, df.time):
    x = df[(df['time']>t-10) & (df['time']<t+10)]
    row = df.loc[i,['a','b','c']]
    res = ((x==row).sum(axis=1)==3).sum()-1
    result.append(res)

我需要一个更快的实现,并查看.rolling了 pandas 数据框的方法,但无法让它与多列和 str 值一起使用。

标签: pythonpandas

解决方案


我只能想办法加快进程

s=pd.Series(df.drop('time',1).apply(tuple,1).map(hash).values,index=df.time)
[ sum(s.loc[x-10:x+10]==y)-1 for x ,y in zip(s.index,s)]
Out[1008]: [1, 1, 2, 2, 2, 0, 1, 1, 0]

推荐阅读