二维numpy数组中具有重复的第一个元素的平均行

时间:2019-01-09 13:52:23

标签: python numpy

我有一个像这样的numpy数组:

print(*a, sep='\n')

我想要做的是平均每个重复的第一项的行数。在此示例中,对第一行和第三行的第二到最后一列取平均。正确的输出应为:

1
2
3 
4

这个答案Average entries with duplicate first element in 2D numpy array与我想做的事情非常相关。

3 个答案:

答案 0 :(得分:3)

这是一种方法:

l = [np.argwhere(i==a[:,0]).ravel() for i in np.unique(a[:,0])]
np.array([a[i].mean(axis=0).tolist() for i in l])

array([[1., 3., 4., 5.],
       [2., 2., 3., 4.],
       [3., 2., 3., 4.]])

说明

关于第一个列表的理解,np.arwhere将为每个unique元素返回一个数组,该数组的行的索引具有相同的第一个元素

l = [np.argwhere(i==a[:,0]).ravel() for i in np.unique(a[:,0])]
[array([0, 2]), array([1]), array([3])]

现在,您只需要根据a中的每个数组对l进行切片,并用以下方法求平均值:

np.array([a[i].mean(axis=0).tolist() for i in l])

array([[1., 3., 4., 5.],
       [2., 2., 3., 4.],
       [3., 2., 3., 4.]])

答案 1 :(得分:2)

你可以用熊猫吗?

import pandas as pd

df = pd.DataFrame(
    [[1, 2, 3, 4],
     [2, 2, 3, 4],
     [1, 4, 5, 6],
     [3, 2, 3, 4]], 
    columns=list('abcd')
    )

df.groupby('a').mean().reset_index().values
# returns:
array([[1, 3, 4, 5],
       [2, 2, 3, 4],
       [3, 2, 3, 4]], dtype=int64)

答案 2 :(得分:1)

方法1

这是NumPy的矢量化-

def groupby_mean(a):
    # Sort array by groupby column
    b = a[a[:,0].argsort()]

    # Get interval indices for the sorted groupby col
    idx = np.flatnonzero(np.r_[True,b[:-1,0]!=b[1:,0],True])

    # Get counts of each group and sum rows based on the groupings & hence averages
    counts = np.diff(idx)
    avg = np.add.reduceat(b[:,1:],idx[:-1],axis=0)/counts.astype(float)[:,None]

    # Finally concatenate for the output in desired format
    return np.c_[b[idx[:-1],0],avg]

方法2

另一个向量化了一个利用matrix-multiplication-

def groupby_mean_matmul(a):
    unq = np.unique(a[:,0])
    m = a[:,0,None] == unq
    return np.c_[unq, m.T.dot(a[:,1:])/m.sum(0)[:,None].astype(float)]

样品运行-

In [51]: a
Out[51]: 
array([[1, 2, 3, 4],
       [2, 2, 3, 4],
       [1, 4, 5, 6],
       [3, 2, 3, 4]])

In [52]: groupby_mean(a)
Out[52]: 
array([[1., 3., 4., 5.],
       [2., 2., 3., 4.],
       [3., 2., 3., 4.]])