【发布时间】:2021-08-17 04:28:54
【问题描述】:
我需要对 pandas 数据框的大量行或列组合执行一些简单的计算。我需要弄清楚如何最有效地做到这一点,因为组合的数量可能会超过十亿。
基本方法很简单——只需对数据帧的子选择执行均值、比较运算符和求和。但是我想出的唯一方法是对组合进行循环,这不是很pythonic,也不是超级有效。由于效率会随着样本数量的增加而变得重要,我希望可能有一些更聪明的方法来做到这一点。
现在我正在构建组合列表,然后选择这些行并使用内置的 pandas 工具进行计算(请参阅下面的伪代码)。一种可能性是将其并行化,这应该很容易。但是,我想知道我是否错过了更有效地执行此操作的更深层次的方法。
一些想法,从大到小排列:
- 是否有一些智能 pandas/python 甚至一些智能线性代数方法来做到这一点?我还没有弄清楚,但想检查一下。
- 坚持使用 pandas 的最佳方法是什么?或者转换为一个 numpy 数组并在那里使用数字索引执行所有操作,然后再转换回更易于理解的数据帧?
- 内置 mean() 是最好的方法,还是应该使用某种 apply()?
- 以任何方式选择行或列是否更快?矩阵是对称的,因此很容易抓取。
- 我目前实际上选择了 18 行,因为 6 行中的每一行实际上都有三个参数略有不同的条目 - 如果出于某种原因选择 6 行比选择 18 行更快,我可以预先将它们组合成单独的行。李>
这是我正在做的一个粗略的草图:
from itertools import combinations
df = from_excel() #Test case is 30 rows & cols
df = df.set_index('Col1') # Column and row 1 are names, rest are the actual matrix values
allSets = combinations(df.columns, 6)
temp = []
for s in allSets:
avg1 = df.loc[list(s)].mean().mean()
cnt1 = df.loc[list(s)].gt(0).sum().sum()
temp.append([s,avg1,cnt1])
dfOut = pd.DataFrame(temp,columns=['Set','Average','Count'])
【问题讨论】:
-
对于初学者,不要使用
allSets = list(combinations(df.columns, 6)),使用allSets = combinations(df.columns, 6),为什么使用list? -
嗯——我认为这是一些尝试传递集合的完整列表而不是一次传递一个集合的剩余部分——我需要循环中的列表,以便数据帧通过列表。在此更正。
-
无论如何,您可以缓存
df.mean()和df.gt(0).sum(),因为您最终会为每个组合重新计算它,这非常浪费。请注意,for 循环根本不是非pythonic,for 循环非常pythonic,尤其是使用itertools,没有更好的方法可以在纯python 中获得组合。 (循环遍历 pandas 数据帧很慢,但这只有在您的操作是可矢量化的情况下才是问题,而哪些组合不是) -
谢谢——我没有注意到缓存这些的机会,但它加快了 30% 以上的速度!并且感谢关于循环是 pythonic 的评论——我一直在寻找一种方法来让事情更加矢量化,但这是有道理的,因为组合是不可矢量化的,所以这是最好的方法。
标签: python pandas performance combinations