提问人:lara_toff 提问时间:8/12/2020 更新时间:8/12/2020 访问量:596
按 Numpy 的中位数分组(不含 Pandas)
Group by median for Numpy (without Pandas)
问:
是否可以在不使用 pandas 的情况下根据另一列的分组计算一列的中位数(并将我的数据保存在 Numpy 数组中)?
例如,如果这是输入:
arr = np.array([[0,1],[0,2],[0,3],[1,4],[1,5],[1,6]])
我希望将其作为输出(使用第一列进行分组,然后取第二列的中位数:
ans = np.array([[0,2],[1,5]])
答:
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谢谢,永远忘记和在,太方便了。prepend
append
np.diff
0赞
Mad Physicist
8/12/2020
@jdehesa。它们相对较新。他们肯定很方便。
评论