Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于Numpy中的其他数组对数组中的数据求和_Python_Arrays_Performance_Numpy_Matrix - Fatal编程技术网

Python 基于Numpy中的其他数组对数组中的数据求和

Python 基于Numpy中的其他数组对数组中的数据求和,python,arrays,performance,numpy,matrix,Python,Arrays,Performance,Numpy,Matrix,我有两个大小相同的2D numpy数组(在本例中简化了大小和内容) ID矩阵: 1 1 1 2 2 1 1 2 2 5 1 1 2 5 5 1 2 2 5 5 2 2 5 5 5 和一个值矩阵: 14.8 17.0 74.3 40.3 90.2 25.2 75.9 5.6 40.0 33.7 78.9 39.3 11.3 63.6 56.7 11.4 75.7 78.4 88.7 58.6 79.6 32.3 35.3 52.5 13.3 我的目标是对第二个矩阵中的值进行计数和求和,这些值

我有两个大小相同的2D numpy数组(在本例中简化了大小和内容)

ID矩阵:

1 1 1 2 2
1 1 2 2 5
1 1 2 5 5
1 2 2 5 5
2 2 5 5 5
和一个值矩阵:

14.8 17.0 74.3 40.3 90.2
25.2 75.9  5.6 40.0 33.7
78.9 39.3 11.3 63.6 56.7
11.4 75.7 78.4 88.7 58.6
79.6 32.3 35.3 52.5 13.3
我的目标是对第二个矩阵中的值进行计数和求和,这些值由第一个矩阵中的ID分组:

1: (8, 336.8)
2: (9, 453.4)
5: (8, 402.4)
我可以在
for
循环中执行此操作,但是当矩阵的大小以千为单位而不是只有5x5和数千个唯一ID时,它需要花费大量时间来处理


numpy是否有聪明的方法或多种方法的组合?

通过几种简单方法的组合,这是可能的:

  • 用于查找每个ID
  • 为每个ID创建一个布尔掩码
  • 将掩码中的1(计数)和掩码为1的值相加
  • 这可以是这样的:

    import numpy as np
    
    ids = np.array([[1, 1, 1, 2, 2],
                    [1, 1, 2, 2, 5],
                    [1, 1, 2, 5, 5],
                    [1, 2, 2, 5, 5],
                    [2, 2, 5, 5, 5]])
    
    values = np.array([[14.8, 17.0, 74.3, 40.3, 90.2],
                       [25.2, 75.9,  5.6, 40.0, 33.7],
                       [78.9, 39.3, 11.3, 63.6, 56.7],
                       [11.4, 75.7, 78.4, 88.7, 58.6],
                       [79.6, 32.3, 35.3, 52.5, 13.3]])
    
    
    for i in np.unique(ids):  # loop through all IDs
        mask = ids == i  # find entries that match current ID
        count = np.sum(mask)  # number of matches
        total = np.sum(values[mask])  # values of matches
        print('{}: ({}, {:.1f})'.format(i, count, total))  #print result
    
    # Output:
    # 1: (8, 336.8)
    # 2: (9, 453.4)
    # 5: (8, 402.4)
    

    下面是一种矢量化方法,用于获取
    ID
    的计数和
    ID-based
    value
    合计值,并结合和-

    要获得作为字典的最终输出,可以使用循环理解来收集求和值,如下所示-

    {i:(IDsums[itr],value_sums[itr]) for itr,i in enumerate(unqID)}
    
    样本运行-

    In [86]: ID
    Out[86]: 
    array([[1, 1, 1, 2, 2],
           [1, 1, 2, 2, 5],
           [1, 1, 2, 5, 5],
           [1, 2, 2, 5, 5],
           [2, 2, 5, 5, 5]])
    
    In [87]: value
    Out[87]: 
    array([[ 14.8,  17. ,  74.3,  40.3,  90.2],
           [ 25.2,  75.9,   5.6,  40. ,  33.7],
           [ 78.9,  39.3,  11.3,  63.6,  56.7],
           [ 11.4,  75.7,  78.4,  88.7,  58.6],
           [ 79.6,  32.3,  35.3,  52.5,  13.3]])
    
    In [88]: unqID,idx,IDsums = np.unique(ID,return_counts=True,return_inverse=True)
        ...: value_sums = np.bincount(idx,value.ravel())
        ...: 
    
    In [89]: {i:(IDsums[itr],value_sums[itr]) for itr,i in enumerate(unqID)}
    Out[89]: 
    {1: (8, 336.80000000000001),
     2: (9, 453.40000000000003),
     5: (8, 402.40000000000003)}
    
    该软件包(免责声明:我是其作者)具有以优雅且矢量化的方式解决此类问题的功能:

    import numpy_indexed as npi
    group_by = npi.group_by(ID.flatten())
    ID_unique, value_sums = group_by.sum(value.flatten())
    ID_count = groupy_by.count    
    

    注:如果您想计算求和和和计数以计算平均值,还有group_by.mean;加上许多其他有用的功能。

    我在问题中提到的
    for
    循环正是如此糟糕,但我应该更清楚。我认为没有for循环,没有一种简洁的方法可以做到这一点。这可能是可能的,但可能会导致非常不可读的代码。如果您只有几个唯一的ID,那么for循环不会影响太大的性能。不管怎样,我会考虑一下…看起来我只是被证明是错的。很好的一个!我不知道
    np的
    return.*
    参数。unique
    @Divakar:谢谢!这正是我所寻找的解决方案,由于矢量化,它的性能很好。
    import numpy_indexed as npi
    group_by = npi.group_by(ID.flatten())
    ID_unique, value_sums = group_by.sum(value.flatten())
    ID_count = groupy_by.count