为什么np.median()会返回多行?

时间:2014-02-26 03:28:28

标签: python arrays numpy

我有一个numpy数组,有100行和16026列。我必须找到每列的中位数。因此,每列的中位数将根据100次观察计算得出(在这种情况下为100行)。我使用以下代码来实现此目的:

for category in categories:
    indices = np.random.randint(0, len(os.listdir(filepath + category)) - 1, 100)
    tempArray = X_train[indices, ]
    medArray = np.median(tempArray, axis=0)
    print(medArray.shape)

这是我得到的输出:

(100, 16026)
(100, 16026)
(100, 16026)
(100, 16026)

我的问题是 - 为什么medArray 100 * 16026而不是1 * 16026的形状?因为我正在计算每列的中位数,所以我预计只有一行有16026列。我在这里错过了什么?

请注意X_train是一个稀疏矩阵。

X_train.shape

输出:

(2034, 16026)

非常感谢这方面的任何帮助。

修改

上述问题已由toarray()函数解决。

tempArray = X_train[indices, ].toarray()

我还认为我是愚蠢的,并且还包括我的中位数计算中的所有零,这就是为什么我一直得到0作为中位数的原因。有没有一种简单的方法可以通过删除/忽略所有列中的零来计算中位数?

3 个答案:

答案 0 :(得分:1)

这真的很奇怪,我认为你应该得到(16026,),我们在这里遗漏了什么:

In [241]:

X_train=np.random.random((1000,16026)) #1000 can be any int.
indices = np.random.randint(0, 60, 100) #60 can be any int.
tempArray = X_train[indices, ]
medArray = np.median(tempArray, axis=0)
print(medArray.shape)

(16026,)

获得2d array结果的唯一方法是:

In [243]:

X_train=np.random.random((100,2,16026))
indices = np.random.randint(0, 60, 100)
tempArray = X_train[indices, ]
medArray = np.median(tempArray, axis=0)
print(medArray.shape)


(2, 16026)

当您输入3d array时。

当它是sparse array时,一种愚蠢的解决方法可能是:

In [319]:

X_train = sparse.rand(112, 16026, 0.5, 'csr') #just make up a random sparse array
indices = np.random.randint(0, 60, 100)
tempArray = X_train[indices, ]
medArray = np.median(tempArray.toarray(), axis=0)
print(medArray.shape)
(16026,)

.toarray()也可能会转到第3行。但不管怎样,这意味着0也算作@zhangxaochen指出。

出于想法,可能会有更好的解释。

答案 1 :(得分:1)

问题在于NumPy不会将稀疏矩阵识别为数组或类似数组的对象。例如,在稀疏矩阵上调用asanyarray会返回一个0D数组,其中一个元素是原始稀疏矩阵:

In [8]: numpy.asanyarray(scipy.sparse.csc_matrix([[1,2,3],[4,5,6]]))
Out[8]:
array(<2x3 sparse matrix of type '<type 'numpy.int64'>'
        with 6 stored elements in Compressed Sparse Column format>, dtype=object)

与大多数NumPy一样,numpy.median依赖于将数组或类似数组的对象作为输入。它所依赖的例程,特别是sort,如果给它一个稀疏矩阵,它将无法理解它们正在看什么。

答案 2 :(得分:1)

我终于能够解决这个问题了。我使用了蒙版数组和以下代码:

 sample = [] 
    sample_size = 50
    idx = matplotlib.mlab.find(newsgroups_train.target==i)
    random_index = []
    for j in range(sample_size):
        random_index.append(randrange(0,len(idx)-1)) 

y = np.ma.masked_where(X_train[sample[0]].toarray() == 0, X_train[sample[0]].toarray())
    medArray = np.ma.median(y, axis=0).filled(0)
    print '============median ' + newsgroups_train.target_names[i] + '============='
    for k,word in enumerate(np.array(vectorizer.get_feature_names())[np.argsort(medArray)[::-1][0:10]]):
        print word + ':' + str(np.sort(medArray)[::-1][k])

这给了我忽略零的中位数。