如何以最快的方式减去2个忽略索引的数据帧。
例如,我想减去:
d1=
x1
0 -3.141593
0 -3.141593
0 -3.141593
1 -2.443461
1 -2.443461
这
d2 =
x2
1 -2.443461
2 -1.745329
3 -1.047198
4 -0.349066
2 0.349066
我尝试过:
我可以这样做,例如:
dsub = d1.reset_index(drop=True) - d2.reset_index(drop=True)
但是,我想以最有效的方式进行减法。我一直在寻找答案,但我只看到了不考虑速度的解决方案。
我如何做到这一点?
编辑根据一些答案,这里有一些时间在我的机器上运行:
对于较小的数据帧:
方法1(a和b):
a: d1.reset_index(drop=True) - d2.reset_index(drop=True)
b: d1.reset_index(drop=True).sub(d2.reset_index(drop=True))
~1024.91 usec/pass
方法2:
d1 - d2.values
~784.79 usec/pass
方法3:
pd.DataFrame(d1.values - d2.values, d1.index, ['x1-x2'])
~653.82 usec/pass
对于非常大的数据帧,请参阅下面的@ MaxU答案。
答案 0 :(得分:7)
你可以这样做:
d1 - d2.values
或:
d1.x1 - d2.x2.values
演示:
In [172]: d1 - d2.values
Out[172]:
x1
0 -0.698132
0 -1.396264
0 -2.094395
1 -2.094395
1 -2.792527
In [173]: d1.x1 - d2.x2.values
Out[173]:
0 -0.698132
0 -1.396264
0 -2.094395
1 -2.094395
1 -2.792527
Name: x1, dtype: float64
更大的DF的时间安排:
In [180]: d1 = pd.concat([d1] * 10**5, ignore_index=True)
In [181]: d2 = pd.concat([d2] * 10**5, ignore_index=True)
In [182]: d1.shape
Out[182]: (500000, 1)
In [183]: %timeit pd.DataFrame(d1.values - d2.values, d1.index, ['x1-x2'])
100 loops, best of 3: 4.07 ms per loop
In [184]: %timeit d1 - d2.values
100 loops, best of 3: 3.99 ms per loop
In [185]: d1 = pd.concat([d1] * 10, ignore_index=True)
In [186]: d2 = pd.concat([d2] * 10, ignore_index=True)
In [187]: d1.shape
Out[187]: (5000000, 1)
In [188]: %timeit pd.DataFrame(d1.values - d2.values, d1.index, ['x1-x2'])
10 loops, best of 3: 19.9 ms per loop
In [189]: %timeit d1 - d2.values
100 loops, best of 3: 14 ms per loop
In [190]: %timeit d1.reset_index(drop=True) - d2.reset_index(drop=True)
1 loop, best of 3: 242 ms per loop
In [191]: %timeit d1.reset_index(drop=True).sub(d2.reset_index(drop=True))
1 loop, best of 3: 242 ms per loop
答案 1 :(得分:3)
答案 2 :(得分:0)
已经有内置的DataFrame减法方法。看看DataFrame.sub。
您的示例中的用法基本上是:
dsub = df1['x1'].reset_index(drop=True).sub(df2['x2'].reset_index(drop=True))
如果DataFrame具有相同的列标题,则您不需要指定列,例如
dsub = df1.reset_index(drop=True).sub(df2.reset_index(drop=True))