【问题标题】:numpy group by, returning original indexes sorted by the resultnumpy group by,返回按结果排序的原始索引
【发布时间】:2021-11-12 14:31:28
【问题描述】:

我有这样的数组:

array([[2, 1],
       [3, 5],
       [2, 1],
       [4, 2],
       [2, 3],
       [5, 3]])

我想做的是按第一列“分组”求和,然后按第二列排序:

array([[2, 5],
       [3, 5],
       [5, 3],
       [4, 2]])

转折来了,我还想从每一行的原始数组中取回索引 在结果数组中,排序:

     2       3     5    4
 [[0,2,4],  [1],  [5], [3] ]

或者如果它容易..我需要获得前 N 个索引......让我们说前 2 个:

     2       3    
  [0,2,4,    1]

没有 pandas,只有纯 numpy。

顺便说一句,我只需要前 N 个项目及其索引 .. 这可以简化流程


尝试应用其中的任何一个:

https://izziswift.com/is-there-any-numpy-group-by-function

【问题讨论】:

  • 更喜欢没有循环......但如果不可能,那就好了
  • np.unique 应用于第一列可能是一个开始。 unique 对其数组进行排序,然后查找相邻的重复项。 pandas 有一个方便的group_by(不一定很快),但numpy 没有。
  • 用于我自己的项目...这是重叠搜索的最后一步

标签: python numpy group-by


【解决方案1】:

我对这个解决方案不满意,无法验证它不会与其他数据中断。它使用引用的想法进行分组,但与add.reduceat 相加。

a = np.array(
      [[2, 1],
       [3, 5],
       [2, 1],
       [4, 2],
       [2, 3],
       [5, 3]])

s = a[:,0].argsort()
b = a[s]
groups, index = np.unique(b[:,0], return_index=True)
# splits = np.split(b[:,1], index[1:]) # if you need the groups
groupsum = np.stack([groups, np.add.reduceat(b[:,1], index)]).T
groupsum[(groupsum[:,1]*(-1)).argsort()]

输出

array([[2, 5],
       [3, 5],
       [5, 3],
       [4, 2]])

获取每个组的索引

np.stack([groups.astype(object),np.split(np.arange(len(a))[s], index[1:])]).T

输出

array([[2, array([0, 2, 4])],
       [3, array([1])],
       [4, array([3])],
       [5, array([5])]], dtype=object)

【讨论】:

    【解决方案2】:

    遗憾的是,在 Numpy 中没有 group-by,但您可以使用 np.unique 来查找唯一元素及其索引,这足以实现您所需要的。一个已识别的键,您可以使用np.add.at 执行基于键的缩减。对于按值排序,您可以使用np.argsort。请参阅this postthis one 了解更多信息。

    keys, index = np.unique(df[:,0], return_inverse=True) # Find the unique key to group
    values = np.zeros(len(keys), dtype=np.int64)          # Sum-based accumulator
    np.add.at(values, index, df[:,1])                     # Key-based accumulation
    tmp = np.hstack([keys[:,None], values[:,None]])       # Build the key-sum 2D array
    res = tmp[tmp[:, 1].argsort()[::-1]]                  # Sort by value
    

    请注意,索引可以很容易地从index 变量(这是一个反向索引)中获得。没有办法用 Numpy 构建它,但这可以使用一个简单的 python 循环在每个键 keys[index[i]] 中存储在字典中的列表中累积索引 i。这是一个例子:

    from collections import defaultdict
    d = defaultdict(list)
    for i in range(len(df)): d[keys[index[i]]].append(i)
    

    【讨论】:

    • 是的,大多数解决方案似乎都需要构建索引... add.at?嗯
    猜你喜欢
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 2011-03-09
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多