Pandas有一个广泛使用的groupby工具,可以根据相应的Map拆分DataFrame,从中可以对每个子组应用计算并重新组合结果。
在NumPy中,如果没有原生的Python for循环,是否可以灵活地实现这一点?如果使用Python循环,则如下所示:
>>> import numpy as np
>>> X = np.arange(10).reshape(5, 2)
>>> groups = np.array([0, 0, 0, 1, 1])
# Split up elements (rows) of `X` based on their element wise group
>>> np.array([X[groups==i].sum() for i in np.unique(groups)])
array([15, 30])
上面15是X
的前三行之和,而30是其余两行之和。
所谓“灵活”,我的意思是我们并不关注一个特定的计算,如求和、计数、最大值等,而是将任何计算传递给分组数组。
如果没有,是否有比上述方法更快的方法?
5条答案
按热度按时间u4vypkhs1#
如何使用scipy稀疏矩阵
我PC上的结果
速度提高10倍以上。
更新!
让我们对“保罗·潘泽”和“丹尼尔·F”的答案进行基准测试。这是一个仅限求和的基准测试。
标准输出
赢家是bincount解。但csr矩阵解也很有趣。
vuv7lop32#
@klim的稀疏矩阵解乍一看似乎与求和有关。然而,我们可以通过在
csr
和csc
之间进行转换来在一般情况下使用它:让我们看一个小例子:
正如我们可以看到的,在转换之后,稀疏矩阵的内部表示产生分组和排序的索引:
我们可以使用稳定的
argsort
得到相同的结果:但是稀疏矩阵实际上更快,即使我们允许
argsort
使用更快的非稳定算法:如果我们需要
argsort
来保持组的排序,则差异会更大:vaqhlq813#
如果您希望更灵活地实现
groupby
,并且可以使用numpy
的任何ufunc
进行分组:v440hwme4#
可能有比这更快的方法(两个操作数现在都在复制),但是:
laik7k3q5#
如果你想把答案扩展到一个ndarray,并且仍然有一个快速的计算,你可以扩展丹尼尔的解决方案:
在本例中,它花费了大约30 ms(创建bin 15 ms+求和15 ms),而不是原始方式中的280 ms。