有效地计算二维数组

时间:2018-02-23 10:52:32

标签: python

我需要在多个一维数组中找到重复的数字以及每次重复的重复次数。这对于一维数组np.unique很有用,但似乎不适用于二维数组,我有搜索类似的答案,但我需要一个更详细的报告。(所有数字的出现次数,位置索引)

Can numpy bincount work with 2D arrays? 这个答案不匹配,我希望得到一个包含更多信息的地图,比如一些数据,我不喜欢回收,也许这不合适,但我会尽力找到方法不要使用循环,因为我对速度的要求非常苛刻。

例如:

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

# The number of occurrences for each number
# int  count
# 0.     0
# 1.     1
# 2.     3
# 3.     1

#need the output:
#Index = the number of statistics, the number of repetitions
[[0 1 3 1]  
 [1 3 1 0]
 [4 1 0 0]]

因为这是循环的一部分,所以您需要一种有效的矢量化方法,以便一次完成更多行的统计信息,并尝试避免再次循环。

我使用了数据包聚合来计算结果。该函数通过构造一个区分行的key1,将数据本身区分为key2,以及所有1的二维数组来实现这一点,虽然能够输出,但我认为这只是临时措施。需要正确的方法。

from numpy_indexed import group_by

def unique2d(x):
    x = x.astype(int); mx = np.nanmax(x)+1

    ltbe = np.tile(np.arange(x.shape[0])[:,None],(1,x.shape[1]))

    vtbe = np.zeros(x.shape).astype(int) + 1

    groups = npi.group_by((ltbe.ravel(),x.ravel().astype(int)))
    unique, median = groups.sum(vtbe.ravel())

    ctbe = np.zeros(x.shape[0]*mx.astype(int)).astype(int)
    ctbe[(unique[0] * mx + unique[1]).astype(int)] = median
    ctbe.shape=(x.shape[0],mx)

    return ctbe

unique2d(a)

>array([[0, 1, 3, 1],
        [1, 3, 1, 0],
        [4, 1, 0, 0]])

希望有很好的建议和算法,谢谢

1 个答案:

答案 0 :(得分:0)

我能想出的最少代码行如下:

import numpy as np
import numpy_indexed as npi

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

row_idx = np.indices(a.shape, dtype=np.int32)[0]
axes, table = npi.Table(row_idx.flatten(), a.flatten()).count()

我讨论过这个,但它不包含任何隐藏的非矢量化for循环;而且我怀疑你无论如何都可以在numpy中做得更快。我也不希望它比现有的解决方案快得多。使用尽可能小的int类型可能有所帮助。

请注意,此函数不假定a的元素构成连续集;轴标签在axes元组中返回;这可能是您正在寻找的行为,也可能不是。修改Table类中的代码以符合当前的布局并不难。

如果速度是您最关心的问题;你的问题可能会很好地映射到numba。