没有循环的Numpy平均位置?

时间:2018-02-12 15:18:54

标签: python numpy

假设我有一个矩阵,其长N个项×长M列(其中M <= N)。我想知道M列中每个N的平均排名。

arr = np.array([
    [0,1],
    [2,0],
    [1,2]
])

我可以循环遍历每个N值,并执行类似下面的操作,但我想知道是否有更好的方法

for n in range(3):
    np.where(arr==n)[0].mean()

修改

很抱歉,我选择的例子似乎引起了一些困惑。为了更好地说明,让我交换字母,因为矩阵中的值是标识符,而不是要计算的数字。

arr = np.array([
    ['A','B'],
    ['C','A'],
    ['B','C']
])

我不是想做一个简单的行平均值。我想说的是

  • 平均等级为0.5(0 + 1)/ 2
  • B平均等级为1.0(0 + 2)/ 2
  • C平均等级为1.5(1 + 2)/ 2

希望这澄清了我的要求

4 个答案:

答案 0 :(得分:2)

看起来你想要沿某个轴获得数组的平均值。您可以使用numpy.meanaxis=参数:

执行此操作
import numpy as np

arr = np.array([
    [0,1],
    [2,0],
    [1,2]
])

np.mean(arr, axis=1)
# [ 0.5  1.   1.5]

答案 1 :(得分:1)

如果你想要行方式

>>> np.mean(arr, axis=1)
array([ 0.5,  1. ,  1.5])

获得排名(作为OP的描述)

首先生成二维索引数组

import numpy as  np

M = 5
N = 7

narray = np.array(np.tile(np.arange(N), M)).reshape(N, M)
print(narray)

输出:

[[0 1 2 3 4]
 [5 6 0 1 2]
 [3 4 5 6 0]
 [1 2 3 4 5]
 [6 0 1 2 3]
 [4 5 6 0 1]
 [2 3 4 5 6]]

现在采取行明智的意思来获得等级

mean_value = np.mean(narray, axis=1)
print(mean_value)

输出

[ 2.   2.8  3.6  3.   2.4  3.2  4. ]

答案 2 :(得分:0)

这是我尝试“改进”您的原始解决方案。我的解决方案的好处是不需要为数组中的每个值重复执行两次(可能非常耗时)操作:np.where(arr==n)(1。找到所有值等于n; 2.找到先前相等为真的元素索引。)

values, inverse, counts = np.unique(arr, return_inverse=True, return_counts=True)
rows = np.argsort(inverse) // len(arr[0])
cumsum = np.cumsum(counts)
avranks = np.add.reduceat(rows, cumsum - cumsum[0]) / counts

然后,对于您的原始数据,

>>> print(avranks)
[0.5 1.  1.5]

答案 3 :(得分:0)

如果每个N项目在每列中恰好出现一次, (即每列都是排名),你可以简单地做:

#arr = np.array([['A','B'],['C','A'],['B','C']])

means = arr.argsort(0).mean(1)
#array([ 0.5,  1. ,  1.5])