避免与熊猫重复操作

时间:2017-09-08 21:26:34

标签: python pandas vectorization

来自另一个问题here

我有一个200万行的DataFrame,类似于这个

final_df = pd.DataFrame.from_dict({
    'ts':    [0,1,2,3,4,5],
    'speed': [5,4,1,4,1,4],
    'temp':  [9,8,7,8,7,8],
    'temp2':  [2,2,7,2,7,2],
    })

我需要使用每行的值运行计算,并将结果作为新列追加,类似于question in this link

我知道有很多组合的速度,温度和temp2重复,如果我drop_duplicates结果DataFrame只有50k行长度,这需要更少的时间来处理,使用这样的应用函数:

def dafunc(row):
    row['r1'] = row['speed'] * row['temp1'] * k1
    row['r2'] = row['speed'] * row['temp2'] * k2

nodup_df = final_df.drop_duplicates(['speed,','temp1','temp2'])
nodup_df = dodup_df.apply(dafunc,axis=1)

上面的代码非常简化了我的实际操作。

到目前为止,我正在尝试使用字典存储结果,并且组合形成的字符串是关键,如果字典已经有了这些结果,我得到它们而不是再次进行计算。

使用Pandas的矢量化操作有更有效的方法吗?

编辑:  最后,生成的DataFrame应如下所示:

#assuming k1 = 0.5, k2 = 1
resulting_df = pd.DataFrame.from_dict({
        'ts':     [0,1,2,3,4,5],
        'speed':  [5,4,1,4,1,4],
        'temp':   [9,8,7,8,7,8],
        'temp2':  [2,2,7,2,7,2],
        'r1':     [22.5,16,3.5,16,3.5,16],
        'r2':     [10,8,7,8,7,8],
        })

1 个答案:

答案 0 :(得分:1)

如果您可以根据列索引从numpy数组中访问列,那么它会快得多,即

final_df['r1'] = final_df.values[:,0]*final_df.values[:,1]*k1
final_df['r2'] = final_df.values[:,0]*final_df.values[:,2]*k2

如果您想一次创建多个列,可以使用for loop,速度类似于

k = [0.5,1]
for i in range(1,3):
     final_df['r'+str(i)] = final_df.values[:,0]*final_df.values[:,i]*k[i-1]

如果删除重复项,则速度会快得多。

输出:

  speed  temp  temp2  ts    r1    r2
0      5     9      2   0  22.5  10.0
1      4     8      2   1  16.0   8.0
2      1     7      7   2   3.5   7.0
3      4     8      2   3  16.0   8.0
4      1     7      7   4   3.5   7.0
5      4     8      2   5  16.0   8.0

适用于小型数据框

%%timeit
final_df['r1'] = final_df.values[:,0]*final_df.values[:,1]*k1
final_df['r2'] = final_df.values[:,0]*final_df.values[:,2]*k2

1000 loops, best of 3: 708 µs per loop

适用于大型数据框

%%timeit
ndf = pd.concat([final_df]*10000)
ndf['r1'] = ndf.values[:,0]*ndf.values[:,1]*k1
ndf['r2'] = ndf.values[:,0]*ndf.values[:,2]*k2

1 loop, best of 3: 6.19 ms per loop