假设我有 2 个数组:
x = [2, 4, 1, 7, 3, 9, 2, 5, 5, 1]
flag = [0, 1, 0, 2, 1, 1, 2, 0, 0, 2]
flag
数组指示x
的每个元素属于哪个"组"。我怎样才能用x
的所有元素的平均值替换x
的每个元素(例如,标志值k
),其对应的flag
值也是k
?
经过这样的转换,x
看起来像:
x = [3.25, 5.33, 3.25, 3.33, 5.33, 5.33, 3.33, 3.25, 3.25, 3.33]
(我可以使用循环来实现这一点,但效率很低。
您可以使用np.bincount
来计算分组均值:
import numpy as np
x = np.array([2, 4, 1, 7, 3, 9, 2, 5, 5, 1])
flag = np.array([0, 1, 0, 2, 1, 1, 2, 0, 0, 2])
total = np.bincount(flag, weights=x)
count = np.bincount(flag)
means = (total/count)[flag]
收益 率
array([ 3.25 , 5.33333333, 3.25 , 3.33333333, 5.33333333,
5.33333333, 3.33333333, 3.25 , 3.25 , 3.33333333])
对于更广义的分组统计信息,还有scipy.stats.binned_statistic
函数。它可以计算分组的平均值、中位数、计数、总和、最小值、最大值统计数据。它也可以接受用户定义的统计函数,但性能(当然)会比内置统计慢。
一种选择是使用熊猫:
import pandas as pd
x = [2, 4, 1, 7, 3, 9, 2, 5, 5, 1]
flag = [0, 1, 0, 2, 1, 1, 2, 0, 0, 2]
s = pd.Series(x,index=flag)
s.groupby(level=0).transform('mean').tolist()
输出:
[3.25,
5.333333333333333,
3.25,
3.3333333333333335,
5.333333333333333,
5.333333333333333,
3.3333333333333335,
3.25,
3.25,
3.3333333333333335]
>>> def grouped_mean(data, flags):
... flag_set = set(flags)
... flags = np.asarray(flags)
... data = np.array(data)
... for s in flag_set:
... m = (flags == s)
... data[m] = np.mean(data[m])
... return data
...
>>> grouped_mean(x, flag)
array([ 3.25 , 5.33333333, 3.25 , 3.33333333, 5.33333333,
5.33333333, 3.33333333, 3.25 , 3.25 , 3.33333333])