有没有numpy的分组函数?

142
有没有numpy函数可以按照下面数组的第一列进行分组?
在网络上找不到什么好的答案。
>>> a
array([[  1, 275],
       [  1, 441],
       [  1, 494],
       [  1, 593],
       [  2, 679],
       [  2, 533],
       [  2, 686],
       [  3, 559],
       [  3, 219],
       [  3, 455],
       [  4, 605],
       [  4, 468],
       [  4, 692],
       [  4, 613]])

希望的输出:

array([[[275, 441, 494, 593]],
       [[679, 533, 686]],
       [[559, 219, 455]],
       [[605, 468, 692, 613]]], dtype=object)
12个回答

1

给定X作为要分组的项目的数组,y(1D数组)作为相应的组,以下函数使用numpy进行分组:

def groupby(X, y):
    y = np.asarray(y)
    X = np.asarray(X)
    y_uniques = np.unique(y)
    return [X[y==yi] for yi in y_uniques]

因此,groupby(a[:,1], a[:,0]) 返回 [array([275, 441, 494, 593]), array([679, 533, 686]), array([559, 219, 455]), array([605, 468, 692, 613])]


0
我使用这个瑞士军刀函数,它可以进行分组,还可以选择性地应用和转换。它大大简化了我的代码。
def group_by(by, func=lambda idx: idx, transform=False, equal_nan=True):
    """
    https://dev59.com/0VoT5IYBdhLWcg3w8S62#77150915
    Groups by the unique values of `by`, calls `func` on each group of
    indices and returns the combined results as a numpy array.
    If `transform=True` the output has as many rows as x (like pandas "transform"),
    and as many rows as unique values in x otherwise (like pandas "apply"),
    ```
    # Examples:
    x = np.array([1, 3, 1, 2, 3])
    y = np.array([5, 4, 3, 2, 1])
    print(group_by(x)) # [array([0, 2]) array([3]) array([1, 4])]
    means = group_by(x, lambda idx: np.mean(y[idx]))
    print(means) # [4.  2.  2.5]
    means = group_by(x, lambda idx: np.mean(y[idx]), transform=True)
    print(means) # [4.  2.5 4.  2.  2.5]
    mins, maxs = group_by(x, lambda idx: [np.min(y[idx]), np.max(y[idx])]).T
    print(mins, maxs) # [3 2 1] [5 2 4]
    for idx in group_by(x):
        print(x[idx[0]], y[idx]) # 1 [5 3]; 2 [2]; 3 [4 1]
    ```
    """
    _, invs, cnts = np.unique(
        by, return_counts=True, return_inverse=True, axis=0, equal_nan=equal_nan
    )
    idxs = np.split(np.argsort(by), np.cumsum(cnts)[:-1])
    out = [func(idx) for idx in idxs]
    if transform:
        out = [out[invs[i]] for i in range(len(by))]
    try:
        out = np.array(out)
    except:
        out = np.array(out, dtype=object)
    return out




x = np.array([1, 1, 1, 2, 7, 7, 3, 2])
y = np.array([0, 1, 2, 3, 4, 5, 6, 7])

print(group_by(x)) # [array([0, 1, 2]), array([3, 7]), array([6]), array([4, 5])]
print(group_by(x, lambda idx: y[idx].mean())) # [1.  5.  6.  4.5]
print(group_by(x, lambda idx: y[idx].mean(), transform=True)) # [1.  1.  1.  5.  4.5 4.5 6.  5. ]
print(group_by(x, lambda idx: [y[idx].min(), y[idx].max()]).T) # [[0 3 6 4] [2 7 6 5]]
print(group_by(x, lambda idx: y[idx])) # [[0, 1, 2], [3, 7], [6], [4, 5]]

更多用法示例在这里:这里这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接