添加具有相同bin分配的numpy数组元素/切片

时间:2017-04-11 16:55:15

标签: python arrays numpy histogram binning

我有一些数组A,数组bins的相应元素包含每一行的bin分配。我想构造一个数组S,这样

S[0, :] = (A[(bins == 0), :]).sum(axis=0)

使用np.stack和列表推导相比,这很容易,但它看起来过于复杂,而且不是非常易读。是否有更通用的方法来对具有bin分配的数组切片求和(或甚至应用某些通用函数)? scipy.stats.binned_statistic沿着右边的行,但要求用于计算函数的bin分配和值是相同的形状(因为我使用切片,情况并非如此)。

例如,如果

A = np.array([[1., 2., 3., 4.],
              [2., 3., 4., 5.],
              [9., 8., 7., 6.],
              [8., 7., 6., 5.]])

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

然后它应该导致

S = np.array([[10., 10., 10., 10.],
              [2.,  3.,  4.,  5. ],
              [8.,  7.,  6.,  5. ]])

2 个答案:

答案 0 :(得分:2)

您可以使用np.add.reduceat

import numpy as np
# index to sort the bins
sort_index = bins.argsort()

# indices where the array needs to be split at
indices = np.concatenate(([0], np.where(np.diff(bins[sort_index]))[0] + 1))

# sum values where the bins are the same
np.add.reduceat(A[sort_index], indices, axis=0)

# array([[ 10.,  10.,  10.,  10.],
#        [  2.,   3.,   4.,   5.],
#        [  8.,   7.,   6.,   5.]])

答案 1 :(得分:2)

以下是matrix-multiplication使用public container -

的方法
(bins == np.arange(bins.max()+1)[:,None]).dot(A)

示例运行 -

In [40]: A = np.array([[1., 2., 3., 4.],
    ...:               [2., 3., 4., 5.],
    ...:               [9., 8., 7., 6.],
    ...:               [8., 7., 6., 5.]])

In [41]: bins = np.array([0, 1, 0, 2])

In [42]: (bins == np.arange(bins.max()+1)[:,None]).dot(A)
Out[42]: 
array([[ 10.,  10.,  10.,  10.],
       [  2.,   3.,   4.,   5.],
       [  8.,   7.,   6.,   5.]])

提升绩效

创建蒙版(bins == np.arange(bins.max()+1)[:,None])的更有效方法就是这样 -

mask = np.zeros((bins.max()+1, len(bins)), dtype=bool)
mask[bins, np.arange(len(bins))] = 1