考虑一下这个熊猫的例子,我将计算列C乘以AB和afloat如果某个条件是通过使用applylambda函数满足的:

import pandas as pd
df = pd.DataFrame({'A':[1,2,3,4,5,6,7,8,9],'B':[9,8,7,6,5,4,3,2,1]})

df['C'] = df.apply(lambda x: x.A if x.B > 5 else 0.1*x.A*x.B, axis=1)

预期结果为:
   A  B    C
0  1  9  1.0
1  2  8  2.0
2  3  7  3.0
3  4  6  4.0
4  5  5  2.5
5  6  4  2.4
6  7  3  2.1
7  8  2  1.6
8  9  1  0.9

问题是,这段代码很慢,我需要在一个具有大约5600万行的数据帧上执行此操作。
上述lambda操作的结果是:
1000 loops, best of 3: 1.63 ms per loop

从计算时间和在大型数据帧上执行此操作时的内存使用情况来看,我假定此操作在执行计算时使用中间序列。
我试图用不同的方式来描述它,包括使用临时列,但是我想到的每一个替代解决方案都更慢。
有没有一种方法可以以不同和更快的方式获得我需要的结果,例如使用%timeit

最佳答案

为了提高性能,您最好使用numpy数组并使用-

a = df.values # Assuming you have two columns A and B
df['C'] = np.where(a[:,1]>5,a[:,0],0.1*a[:,0]*a[:,1])

运行时测试
def numpy_based(df):
    a = df.values # Assuming you have two columns A and B
    df['C'] = np.where(a[:,1]>5,a[:,0],0.1*a[:,0]*a[:,1])

计时-
In [271]: df = pd.DataFrame(np.random.randint(0,9,(10000,2)),columns=[['A','B']])

In [272]: %timeit numpy_based(df)
1000 loops, best of 3: 380 µs per loop

In [273]: df = pd.DataFrame(np.random.randint(0,9,(10000,2)),columns=[['A','B']])

In [274]: %timeit df['C'] = df.A.where(df.B.gt(5), df[['A', 'B']].prod(1).mul(.1))
100 loops, best of 3: 3.39 ms per loop

In [275]: df = pd.DataFrame(np.random.randint(0,9,(10000,2)),columns=[['A','B']])

In [276]: %timeit df['C'] = np.where(df['B'] > 5, df['A'], 0.1 * df['A'] * df['B'])
1000 loops, best of 3: 1.12 ms per loop

In [277]: df = pd.DataFrame(np.random.randint(0,9,(10000,2)),columns=[['A','B']])

In [278]: %timeit df['C'] = np.where(df.B > 5, df.A, df.A.mul(df.B).mul(.1))
1000 loops, best of 3: 1.19 ms per loop

近距离观察
让我们仔细看看Numpy的数字处理能力,并将其与熊猫进行比较。-
# Extract out as array (its a view, so not really expensive
#   .. as compared to the later computations themselves)

In [291]: a = df.values

In [296]: %timeit df.values
10000 loops, best of 3: 107 µs per loop

案例1:使用numpy数组并使用numpy。其中:
In [292]: %timeit np.where(a[:,1]>5,a[:,0],0.1*a[:,0]*a[:,1])
10000 loops, best of 3: 86.5 µs per loop

同样,分配到新列中:np.where也不会非常昂贵。-
In [300]: %timeit df['C'] = np.where(a[:,1]>5,a[:,0],0.1*a[:,0]*a[:,1])
1000 loops, best of 3: 323 µs per loop

案例2:使用熊猫数据框架,并使用其df['C']方法(无numpy)
In [293]: %timeit df.A.where(df.B.gt(5), df[['A', 'B']].prod(1).mul(.1))
100 loops, best of 3: 3.4 ms per loop

案例3:使用熊猫数据帧(无numpy数组),但使用-
In [294]: %timeit np.where(df['B'] > 5, df['A'], 0.1 * df['A'] * df['B'])
1000 loops, best of 3: 764 µs per loop

案例4:再次使用熊猫数据帧(无numpy数组),但使用-
In [295]: %timeit np.where(df.B > 5, df.A, df.A.mul(df.B).mul(.1))
1000 loops, best of 3: 830 µs per loop

关于python - Pandas :如何更快地申请数据框?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41588034/

10-12 14:12
查看更多