我有一个带有混合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)
我需要更快的实现,并且研究了pandas数据框的.rolling
方法,但无法使其与多列和str值一起使用。
答案 0 :(得分:1)
我只能想到一种加快流程的方法
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]