使用NumPy数组进行分组平均值和标准差计算

5

我有一组数据(X,Y)。我的自变量值X不是唯一的,因此有多个重复值,我想输出一个新数组,其中包含:X_unique,它是X的唯一值列表。 Y_mean是与X_unique对应的所有Y值的平均值。 Y_std是与X_unique对应的所有Y值的标准偏差。

x = data[:,0]
y = data[:,1]

1
你能否在你的问题中添加一个最小化、完整化和可验证化的示例 - Mazdak
请查看https://dev59.com/wG855IYBdhLWcg3wYjOF。 - das-g
1
附注:如果您正在处理实际数据,使用pandas比裸的numpy更容易。如果您的data是一个DataFrame而不是一个ndarray,那么像df.groupby(0)[1].agg(["mean", "std"])这样的东西就可以工作了。 - DSM
3个回答

4
您可以使用来自scipy.stats的binned_statistic,它支持在1D数组中应用各种统计函数以分块方式进行。要获取这些块,我们需要对其进行排序并获取移位的位置(块变化的位置),np.unique将非常有用。将所有这些放在一起,下面是一个实现 -
from scipy.stats import binned_statistic as bstat

# Sort data corresponding to argsort of first column
sdata = data[data[:,0].argsort()]

# Unique col-1 elements and positions of breaks (elements are not identical)
unq_x,breaks = np.unique(sdata[:,0],return_index=True)
breaks = np.append(breaks,data.shape[0])

# Use binned statistic to get grouped average and std deviation values
idx_range = np.arange(data.shape[0])
avg_y,_,_ = bstat(x=idx_range, values=sdata[:,1], statistic='mean', bins=breaks)
std_y,_,_ = bstat(x=idx_range, values=sdata[:,1], statistic='std', bins=breaks)

binned_statistic的文档中,我们也可以使用自定义的统计函数:

function:一个用户定义的函数,它接受一个值的一维数组,并输出单个数字统计量。该函数将在每个箱中的值上调用。空箱子将被表示为function([]),如果这返回错误,则为NaN。

样例输入,输出 -

In [121]: data
Out[121]: 
array([[2, 5],
       [2, 2],
       [1, 5],
       [3, 8],
       [0, 8],
       [6, 7],
       [8, 1],
       [2, 5],
       [6, 8],
       [1, 8]])

In [122]: np.column_stack((unq_x,avg_y,std_y))
Out[122]: 
array([[ 0.        ,  8.        ,  0.        ],
       [ 1.        ,  6.5       ,  1.5       ],
       [ 2.        ,  4.        ,  1.41421356],
       [ 3.        ,  8.        ,  0.        ],
       [ 6.        ,  7.5       ,  0.5       ],
       [ 8.        ,  1.        ,  0.        ]])

之前不知道 binned_statistic 的存在。在不久的将来,我可能会经常使用它!我曾经写过 Cython 代码来实现类似的功能哈哈!谢谢! - Imanol Luengo
@imaluengo 我知道它可以得到平均值,但我不确定标准差,结果它起作用了!源代码在这个答案里 - https://dev59.com/vorda4cB1Zd3GeqPJC9q#29894547。使用NumPy数组本地化的东西看起来真的很棒! - Divakar

2
x_unique  = np.unique(x)
y_means = np.array([np.mean(y[x==u]) for u in x_unique])
y_stds = np.array([np.std(y[x==u]) for u in x_unique])

1
Pandas是为这样的任务而设计的:
data=np.random.randint(1,5,20).reshape(10,2)
import pandas
pandas.DataFrame(data).groupby(0).mean()

提供

          1
0          
1  2.666667
2  3.000000
3  2.000000
4  1.500000

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