如何根据 Pandas 数据框中的两行加快分数计算?

How do you speed up a score calculation based on two rows in a Pandas Dataframe?

TLDR:如何调整 for 循环以获得更快的执行时间:

import numpy as np
import pandas as pd
import time

np.random.seed(0)

# Given a DataFrame df and a row_index
df = pd.DataFrame(np.random.randint(0, 3, size=(30000, 50)))
target_row_index = 5

start = time.time()

target_row = df.loc[target_row_index]
result = []

# Method 1: Optimize this for-loop
for row in df.iterrows():
    """
    Logic of calculating the variables check and score: 
    if the values for a specific column are 2 for both rows (row/target_row), it should add 1 to the score
    if for one of the rows the value is 1 and for the other 2 for a specific column, it should subtract 1 from the score.
    """
    check = row[1]+target_row  # row[1] takes 30 microseconds per call
    score = np.sum(check == 4) - np.sum(check == 3) # np.sum takes 47 microseconds per call
    result.append(score)

print(time.time()-start)

# Goal: Calculate the list result as efficient as possible

# Method 2: Optimize Apply
def add(a, b):
    check = a + b
    return np.sum(check == 4) - np.sum(check == 3)
    
start = time.time()
q = df.apply(lambda row : add(row, target_row), axis = 1)
print(time.time()-start)

所以我有一个大小为 30'000 的数据框和一个具有给定行索引的目标行。现在我想通过计算分数将这一行与数据集中的所有其他行进行比较。分数计算如下:

  1. 如果特定列的值对于两行都是 2,则应该将分数加 1
  2. 如果其中一行的值为 1,而对于特定列的其他 2 行,则应从分数中减去 1。

结果就是我们刚刚计算的所有分数的列表。

因为我需要经常执行这段代码,所以我想优化它以提高性能。 非常感谢任何帮助。

我已经阅读了Optimization when using Pandas您是否可以推荐更多资源?谢谢

如果您愿意将 df 转换为 NumPy 数组,NumPy 有一些非常好的矢量化可以提供帮助。我使用 NumPy 的代码如下:

df = pd.DataFrame(np.random.randint(0, 3, size=(30000, 50)))
target_row_index = 5

start_time = time.time()

# Converting stuff to NumPy arrays
target_row = df.loc[target_row_index].to_numpy()
np_arr = df.to_numpy()

# Calculations
np_arr += target_row
check = np.sum(np_arr == 4, axis=1) - np.sum(np_arr == 3, axis=1)
result = list(check)

end_time = time.time()
print(end_time - start_time)

你的完整代码(对我来说在 Google Colab 上)输出时间 14.875332832336426 s,而上面的 NumPy 代码输出时间 0.018691539764404297 s,并且当然,result 列表在两种情况下都是相同的。

请注意,一般来说,如果您的计算是纯数值的,NumPy 实际上总是比 Pandasfor 循环更好。 Pandas 真的很适合字符串,当你需要列名和行名时,但是对于纯数字,NumPy 是由于矢量化的方式。