跨不等大小数组的 Numpy 均值计算
Numpy median-of-means computation across unequal-sized array
假设 numpy
数组 X
的形状 m x n
和类型 float64
。 X
的行需要通过逐元素的均值计算。具体来说,m
行索引被划分为 b
个“桶”,每个桶包含 m/b
个这样的索引。接下来,在每个存储桶中,我计算平均值,并在结果平均值中计算最终的中值。
一个阐明它的例子是
import numpy as np
m = 10
n = 10000
# A random data matrix
X = np.random.uniform(low=0.0, high=1.0, size=(m,n)).astype(np.float64)
# Number of buckets to split rows into
b = 5
# Partition the rows of X into b buckets
row_indices = np.arange(X.shape[0])
buckets = np.array(np.array_split(row_indices, b))
X_bucketed = X[buckets, :]
# Compute the mean within each bucket
bucket_means = np.mean(X_bucketed, axis=1)
# Compute the median-of-means
median = np.median(bucket_means, axis=0)
# Edit - Method 2 (based on answer)
np.random.shuffle(row_indices)
X = X[row_indices, :]
buckets2 = np.array_split(X, b, axis=0)
bucket_means2 = [np.mean(x, axis=0) for x in buckets2]
median2 = np.median(np.array(bucket_means2), axis=0)
如果 b
除 m
,则此程序工作正常,因为 np.array_split()
导致将索引分成相等的部分,并且数组 buckets
是一个二维数组。
但是,如果b
不除m
,则不起作用。在那种情况下,np.array_split() 仍然分成 b
个桶,但大小不等,这对我的目的来说很好。例如,如果 b = 3
它会将索引 {0,1,...,9} 拆分为 [0 1 2 3]、[4 5 6] 和 [7 8 9]。这些数组不能相互堆叠,因此数组 buckets
不是二维数组,它不能用于索引 X_bucketed
.
我怎样才能使这个工作适用于大小不等的桶,即让程序计算每个桶内的平均值(不管它的大小),然后计算桶的中值?
我不能完全掌握masked arrays,我不确定这些是否可以在这里使用。
您可以考虑分别计算每个桶的均值,然后堆叠并计算中位数。您也可以直接使用 array_split
到 X,无需使用切片索引数组对其进行索引(也许这是您的主要问题?)。
m = 11
n = 10000
# A random data matrix
X = np.random.uniform(low=0.0, high=1.0, size=(m,n)).astype(np.float64)
# Number of buckets to split rows into
b = 5
# Partition the rows of X into b buckets
buckets = np.array_split(X, 2, axis = 0)
# Compute the mean within each bucket
b_means = [np.mean(x, axis=0) for x in buckets]
# Compute the median-of-means
median = np.median(np.array(b_means), axis=0)
print(median) #(10000,) shaped array
假设 numpy
数组 X
的形状 m x n
和类型 float64
。 X
的行需要通过逐元素的均值计算。具体来说,m
行索引被划分为 b
个“桶”,每个桶包含 m/b
个这样的索引。接下来,在每个存储桶中,我计算平均值,并在结果平均值中计算最终的中值。
一个阐明它的例子是
import numpy as np
m = 10
n = 10000
# A random data matrix
X = np.random.uniform(low=0.0, high=1.0, size=(m,n)).astype(np.float64)
# Number of buckets to split rows into
b = 5
# Partition the rows of X into b buckets
row_indices = np.arange(X.shape[0])
buckets = np.array(np.array_split(row_indices, b))
X_bucketed = X[buckets, :]
# Compute the mean within each bucket
bucket_means = np.mean(X_bucketed, axis=1)
# Compute the median-of-means
median = np.median(bucket_means, axis=0)
# Edit - Method 2 (based on answer)
np.random.shuffle(row_indices)
X = X[row_indices, :]
buckets2 = np.array_split(X, b, axis=0)
bucket_means2 = [np.mean(x, axis=0) for x in buckets2]
median2 = np.median(np.array(bucket_means2), axis=0)
如果 b
除 m
,则此程序工作正常,因为 np.array_split()
导致将索引分成相等的部分,并且数组 buckets
是一个二维数组。
但是,如果b
不除m
,则不起作用。在那种情况下,np.array_split() 仍然分成 b
个桶,但大小不等,这对我的目的来说很好。例如,如果 b = 3
它会将索引 {0,1,...,9} 拆分为 [0 1 2 3]、[4 5 6] 和 [7 8 9]。这些数组不能相互堆叠,因此数组 buckets
不是二维数组,它不能用于索引 X_bucketed
.
我怎样才能使这个工作适用于大小不等的桶,即让程序计算每个桶内的平均值(不管它的大小),然后计算桶的中值?
我不能完全掌握masked arrays,我不确定这些是否可以在这里使用。
您可以考虑分别计算每个桶的均值,然后堆叠并计算中位数。您也可以直接使用 array_split
到 X,无需使用切片索引数组对其进行索引(也许这是您的主要问题?)。
m = 11
n = 10000
# A random data matrix
X = np.random.uniform(low=0.0, high=1.0, size=(m,n)).astype(np.float64)
# Number of buckets to split rows into
b = 5
# Partition the rows of X into b buckets
buckets = np.array_split(X, 2, axis = 0)
# Compute the mean within each bucket
b_means = [np.mean(x, axis=0) for x in buckets]
# Compute the median-of-means
median = np.median(np.array(b_means), axis=0)
print(median) #(10000,) shaped array