将 2 个 Pandas 列相乘并获得值之和的最快方法

问题描述 投票:0回答:2

我正在进行大量计算,将一个名为“因子”的 pandas 列与另一个名为“值”的列相乘,然后计算乘法的总和。

两列的长度通常约为 200 行。鉴于这是我在当前项目中进行了数千次的计算,我需要它尽可能快

代码的缩小版本如下所示(只有 4 行)

  dict = {'factor': [0.25,0.25,0.25,0.25],
        'value': [22000,25000,27000,35000] }

df = pd.DataFrame(dict, columns= ['factor', 'value'])

print((df['factor'] * df['value']).sum())

打印出27250。

有没有办法更快地获得相同的结果?

python pandas
2个回答
1
投票

您可以使用

numpy
- 通过
values
将列转换为一维数组,然后
numpy.sum
:

np.random.seed(456)

d = {'factor': np.random.rand(200),
     'value': np.random.randint(1000, size=200)}

df = pd.DataFrame(d, columns= ['factor', 'value'])
#print (df)

In [139]: %timeit ((df['factor'] * df['value']).sum())
245 µs ± 2.64 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [140]: %timeit (np.sum((df['factor'].values * df['value'].values)))
20.6 µs ± 328 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

如果可能某些缺失值在输出中得到 NaN,因此需要

numpy.nansum
来防止它:

np.random.seed(456)

d = {'factor': np.random.rand(200),
     'value': np.random.randint(1000, size=200)}

df = pd.DataFrame(d, columns= ['factor', 'value'])
df['value'] = df['value'].mask(df['value'] > 700)
#print (df)

In [144]: %timeit ((df['factor'] * df['value']).sum())
235 µs ± 8.65 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [145]: %timeit (np.nansum((df['factor'].values * df['value'].values)))
33.3 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

0
投票

我重复使用 DF 柱或其 NP 对应物的实验,得到了与上面报道的不同的结果。我确实意识到它们很久以前就被共享了。看来现在的情况有所不同。这是我在一台配备 Intel Core i7-13700K 的空闲 Windows 11 计算机上使用 Pandas 2.2.2 和 Python 3.11.9 运行的程序。

df = pd.DataFrame()
x = "x"; y = "y"; z = "z"

df[x] = np.arange(100*1000*1000)
df[y] = np.arange(100*1000*1000)
n = 100

t1 = datetime.now()
for i in range(0, n):
    pass
t2 = datetime.now(); print("Plain loop", t2-t1)

t1 = datetime.now()
for i in range(0, n):
    a = (df[x]*df[y]).sum()
t2 = datetime.now(); print("DF columns", t2-t1)

t1 = datetime.now()
for i in range(0, n):
    a = np.sum(df[x].values * df[y].values)
t2 = datetime.now(); print("NP arrays", t2-t1)

...这是输出:

Plain loop 0:00:00
DF columns 0:00:08.807886
NP arrays  0:00:11.704078

粗略地说,NP 数组方法大约慢 33%。经过多次手动运行后,结果仍然相同。我发现这令人惊讶,并想将这个新结果添加到这个旧序列中。

© www.soinside.com 2019 - 2024. All rights reserved.