Python 不等大小数组平均值计算的Numpy中值

Python 不等大小数组平均值计算的Numpy中值,python,numpy,median-of-medians,Python,Numpy,Median Of Medians,假设一个numpy数组X的形状mxn并键入float64。X的行需要通过元素平均值计算的中位数。具体地说,m行索引被划分为b“bucket”,每个bucket包含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

假设一个
numpy
数组
X
的形状
mxn
并键入
float64
X
的行需要通过元素平均值计算的中位数。具体地说,
m
行索引被划分为
b
“bucket”,每个bucket包含
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()
会将索引等分,而array
bucket
是一个2D数组

但是,如果
b
不除以
m
,则它不起作用。在这种情况下,仍然会拆分为
b
存储桶,但大小不一,这对我来说很好。例如,如果
b=3
它将把索引{0,1,…,9}分成[0123]、[456]和[789]。这些数组不能相互堆叠,因此数组
bucket
不是二维数组,不能用于索引
X\u bucketed

对于大小不等的桶,我如何才能做到这一点,即让程序计算每个桶内的平均值(无论大小),然后计算桶间的中值


我不能完全掌握,我不确定这里是否可以使用。

你可以单独计算每个桶的平均值,然后叠加并计算中值。您也可以直接使用

array\u split
对X进行索引,而无需使用切片索引数组对其进行索引(可能这是您的主要问题?)


切片只是因为我正在洗牌行(为了简洁起见省略了,但现在添加了)。我已经将您的想法改编为我的代码(请参见编辑),它似乎按照预期工作。我只是想知道你能否给我一些关于这两种方法在速度方面的比较的见解?我担心潜在的瓶颈,因为这应该是大规模的。@mgus我很快在一些不同的规模上测试了它,似乎第二种方法总是更快,这不是我所期望的。很抱歉,我对时间效率没有太多见解。也许这篇文章会有帮助。
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