按 Numpy 的中位数分组(不含 Pandas)

Group by median for Numpy (without Pandas)

提问人:lara_toff 提问时间:8/12/2020 更新时间:8/12/2020 访问量:596

问:

是否可以在不使用 pandas 的情况下根据另一列的分组计算一列的中位数(并将我的数据保存在 Numpy 数组中)?

例如,如果这是输入:

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

我希望将其作为输出(使用第一列进行分组,然后取第二列的中位数:

ans = np.array([[0,2],[1,5]])
python numpy 分组 by 中位数

评论


答:

3赞 jdehesa 8/12/2020 #1

如果您出于某种原因想避免使用 Pandas,这里有一种可能性可以进行该计算。请注意,在一般情况下,中位数不是整数值(除非你将其舍入或下限),因为对于偶数大小的组,它将是最中间两个元素的平均值,因此你不能在单个常规数组中同时拥有整数组 id 和中值(尽管在结构化数组中可以)。

import numpy as np

def grouped_median(group, value):
    # Sort by group and value
    s = np.lexsort([value, group])
    arr2 = arr[s]
    group2 = group[s]
    value2 = value[s]
    # Look for group boundaries
    w = np.flatnonzero(np.diff(group2, prepend=group2[0] - 1, append=group2[-1] + 1))
    # Size of each group
    wd = np.diff(w)
    # Mid points of each group
    m1 = w[:-1] + wd // 2
    m2 = m1 - 1 + (wd % 2)
    # Group id
    group_res = group2[m1]
    # Group median value
    value_res = (value2[m1] + value2[m2]) / 2  # Use `// 2` or round for int result
    return group_res, value_res

# Test
arr = np.array([[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [1, 6]])
group_res, value_res = grouped_median(arr[:, 0], arr[:, 1])
# Print
for g, v in zip(group_res, value_res):
    print(g, v)
    # 0 2.0
    # 1 5.0
# As a structured array
res = np.empty(group_res.shape, dtype=[('group', group_res.dtype),
                                       ('median', value_res.dtype)])
res['group'] = group_res
res['median'] = value_res
print(res)
# [(0, 2.) (1, 5.)]

评论

1赞 Mad Physicist 8/12/2020
@lara_toff。这是非常有效的。把它粘在某个地方的函数中,忘记实现。
1赞 Mad Physicist 8/12/2020
我会写成.然后下一行也消失了w = np.where(group[:-1] != group[1:])[0]w = np.flatnonzero(np.diff(group, prepend=group[0] - 1, append=group[-1] + 1))
0赞 jdehesa 8/12/2020
@MadPhysicist谢谢,永远忘记和在,太方便了。prependappendnp.diff
0赞 Mad Physicist 8/12/2020
@jdehesa。它们相对较新。他们肯定很方便。