【问题标题】:Numpy: Sample group of indices with different valuesNumpy:具有不同值的索引样本组
【发布时间】:2019-09-11 08:28:51
【问题描述】:

给定一些 numpy 数组 a

array([2,2,3,3,2,0,0,0,2,2,3,2,0,1,1,0])

获取所有n 索引组的最佳方法是什么,每个索引组在a 中具有不同 值?

显然没有组大于a 中唯一元素的数量,这里是 4。

例如,一组大小为4的

array([0,2,5,13])

考虑到a 可能会很长,比如说最多 250k。

如果结果变得太大,也可能不希望计算所有这些组,而只计算第一个 k 请求。

【问题讨论】:

  • 那么,唯一元素的第一次出现就足够了吗?
  • 不,我想要更多。最好是第一个k
  • 所以参数是n代表组的大小和k代表组的数量,[]是有效的返回
  • 你能详细说明“更多”吗?比如你为什么选择0 而不是1 甚至4 这两个数字?
  • 没关系。这可能不是确定性的。

标签: python numpy grouping sampling


【解决方案1】:

对于整数输入,我们可以有一个基于this post的解决方案-

In [41]: sidx = a.argsort() # use kind='mergesort' for first occurences

In [42]: c = np.bincount(a)

In [43]: np.sort(sidx[np.r_[0,(c[c!=0])[:-1].cumsum()]])
Out[43]: array([ 0,  2,  5, 13])

另一种与以前的通用输入方法密切相关 -

In [44]: b = a[sidx]

In [45]: np.sort(sidx[np.r_[True,b[:-1]!=b[1:]]])
Out[45]: array([ 0,  2,  5, 13])

另一个numba 用于内存效率和性能,以选择沿这些唯一组的第一个索引以及额外的k arg -

from numba import njit

@njit
def _numba1(a, notfound, out, k):
    iterID = 0
    for i,e in enumerate(a):
        if notfound[e]:
            notfound[e] = False
            out[iterID] = i
            iterID += 1
        if iterID>=k:
            break
    return out

def unique_elems(a, k, maxnum=None):
    # feed in max of the input array as maxnum value if known
    if maxnum is None:
        L = a.max()+1
    else:
        L = maxnum+1
    notfound = np.ones(L, dtype=bool)
    out = np.ones(k, dtype=a.dtype)
    return _numba1(a, notfound, out, k)

示例运行 -

In [16]: np.random.seed(0)
    ...: a = np.random.randint(0,10,200)

In [17]: a
Out[17]: 
array([5, 0, 3, 3, 7, 9, 3, 5, 2, 4, 7, 6, 8, 8, 1, 6, 7, 7, 8, 1, 5, 9,
       8, 9, 4, 3, 0, 3, 5, 0, 2, 3, 8, 1, 3, 3, 3, 7, 0, 1, 9, 9, 0, 4,
       7, 3, 2, 7, 2, 0, 0, 4, 5, 5, 6, 8, 4, 1, 4, 9, 8, 1, 1, 7, 9, 9,
       3, 6, 7, 2, 0, 3, 5, 9, 4, 4, 6, 4, 4, 3, 4, 4, 8, 4, 3, 7, 5, 5,
       0, 1, 5, 9, 3, 0, 5, 0, 1, 2, 4, 2, 0, 3, 2, 0, 7, 5, 9, 0, 2, 7,
       2, 9, 2, 3, 3, 2, 3, 4, 1, 2, 9, 1, 4, 6, 8, 2, 3, 0, 0, 6, 0, 6,
       3, 3, 8, 8, 8, 2, 3, 2, 0, 8, 8, 3, 8, 2, 8, 4, 3, 0, 4, 3, 6, 9,
       8, 0, 8, 5, 9, 0, 9, 6, 5, 3, 1, 8, 0, 4, 9, 6, 5, 7, 8, 8, 9, 2,
       8, 6, 6, 9, 1, 6, 8, 8, 3, 2, 3, 6, 3, 6, 5, 7, 0, 8, 4, 6, 5, 8,
       2, 3])

In [19]: unique_elems(a, k=6)
Out[19]: array([0, 1, 2, 4, 5, 8])

【讨论】:

    【解决方案2】:

    使用Numpy.unique 完成这项工作。还有其他几个选项,例如可以返回每个唯一项目在 a 中出现的次数。

    import numpy as np
    
    # Sample data
    a = np.array([2,2,3,3,2,0,0,0,2,2,3,2,0,1,1,0])
    
    # The unique values are in 'u'
    # The indices of the first occurence of the unique values are in 'indices'
    u, indices = np.unique(a, return_index=True)
    

    【讨论】:

      猜你喜欢
      • 2018-10-13
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2022-10-30
      • 2019-01-09
      • 2014-01-15
      相关资源
      最近更新 更多