【问题标题】:How to sum the values of an array based on reference values from another array如何根据来自另一个数组的参考值对数组的值求和
【发布时间】:2018-12-26 19:13:46
【问题描述】:

假设 b 数组的唯一值具有相同的维度和形状,我如何获得 a 数组的总和?

换句话说,对于数组a 的每个值,我希望有一个由数组b 的总和组成的输出。 (在下面的示例中:值 1 的总和 = xxx,值 2 的总和 = yyy... 值 11 的总和 = zzz)

a = [[ 5  1 10 11  6]
     [ 5  3  8 10  9]
     [ 2  1 10  8  7]
     [ 7 10  7  8 11]
     [10 10  3  0 11]]
b = [[508 220 316 557 737]
    [625 419 161 736 426]
    [389 608 760 885 232] 
    [396 309 522 204 842]
    [403 831 225 549 797]]

【问题讨论】:

  • 您能否重新表述您的问题,很难理解。
  • 好的,发布预期结果

标签: python numpy


【解决方案1】:

您可以使用numpy

import numpy as np

a = np.array(
    [[ 5,  1, 10, 11,  6],
     [ 5,  3,  8, 10,  9],
     [ 2,  1, 10,  8,  7],
     [ 7, 10,  7,  8, 11],
     [10, 10,  3,  0, 11]])
b = np.array(
    [[508, 220, 316, 557, 737],
    [625, 419, 161, 736, 426],
    [389, 608, 760, 885, 232],
    [396, 309, 522, 204, 842],
    [403, 831, 225, 549, 797]])

values = np.unique(a)
# will be [ 0  1  2  3  5  6  7  8  9 10 11]

out = {}
for value in values:
    out[value] = sum(b[np.where(a==value)])

print(out)
# {0: 549, 1: 828, 2: 389, 3: 644, 5: 1133, 6: 737, 7: 1150, 8: 1250, 9: 426, 10: 3355, 11: 2196}

或者使用 dict 理解,全部在一行中:

out = {value: sum(b[np.where(a==value)]) for value in np.unique(a)}

【讨论】:

    【解决方案2】:

    Pandas 是处理此类事情的直接有效方式:

    df=pd.DataFrame(data=b.ravel(),index=a.ravel()) 
    sums=df.groupby(level=0).sum()
    
    #        0
    # 0    549
    # 1    828
    # 2    389
    # 3    644
    # 5   1133
    # 6    737
    # 7   1150
    # 8   1250
    # 9    426
    # 10  3355
    # 11  2196
    

    基准测试:

    a=np.random.randint(0,10**4,size=10**5)
    b=np.random.randint(0,10**6,size=10**5)
    
    In [19]: %timeit pd.DataFrame(b,a).groupby(level=0).sum()
    58.7 ms ± 12.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [20]: %timeit for aa, bb in zip(a,b):result[aa] += bb
    223 ms ± 36.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [21]: %timeit for value in np.unique(a): out[value] = np.sum(b[np.where(a==value)])
    5.67 s ± 933 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

    • 谢谢!我正在使用您推荐的解决方案。但是,我正在使用蒙特卡洛斯模拟(运行脚本时应该创建 10000 df,但它返回内存错误。关于如何克服这个问题的任何想法?我使用的是 Python 2.7 32bit跨度>
    【解决方案3】:

    或手动:

    from itertools import chain
    from collections import defaultdict
    
    a = [[ 5,  1, 10, 11,  6],
         [ 5,  3,  8, 10,  9],
         [ 2,  1, 10,  8,  7],
         [ 7, 10,  7,  8, 11],
         [10, 10,  3,  0, 11]]
    b = [[508, 220, 316, 557, 737],
        [625, 419, 161, 736, 426],
        [389, 608, 760, 885, 232],
        [396, 309, 522, 204, 842],
        [403, 831, 225, 549, 797]]
    
    result = defaultdict(int)
    
    for aa, bb in zip(chain(*a), chain(*b)):
        result[aa] += bb
    
    print(result)
    
    #defaultdict(<class 'int'>, {5: 1133, 1: 828, 10: 3355, 11: 2196, 6: 737, 3: 644, 8: 1250, 9: 426, 2: 389, 7: 1150, 0: 549})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      相关资源
      最近更新 更多