不使用循环,如何计算Numpy数组的平均位置?

3
假设我有一个矩阵,它有N个项目和M列(其中M≤N)。我想知道每个N在M列中的平均排名。
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']
])

我不是要做简单的逐行平均。我想表达的是:

  • A 的平均排名是 0.5 (0 + 1)/ 2
  • B 的平均排名是 1.0 (0 + 2)/ 2
  • C 的平均排名是 1.5 (1 + 2)/ 2

希望这样可以澄清我的请求。


2
你是指 np.mean(arr, axis=1) 吗? - undefined
1
请问什么是“平均排名”? - undefined
为什么要对数组arr中等于某个数字n的元素的索引进行平均计算:np.where(arr==n)[0].mean() - undefined
1
我添加了一份澄清说明,以显示我确实正在计算索引的平均值,因为我想要的是平均索引值。我并不想要值本身的平均值,因为它们只是ID。 - undefined
4个回答

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
如果您想要逐行计算平均值
>>> 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. ]

我添加了澄清说明,以表明我确实正在对索引进行平均,因为我想要平均索引值。我不想要值本身的平均值,因为它们只是ID。- OP说。这里的结论是什么? - undefined
@ElPresidente 你的意见是什么?我是否误解了你的问题? - undefined
如果他处理的是相对位置,你是对的。如果他处理的是在范围[0 - N-1]内的值,我的方法也能行得通。对吗? - undefined
楼主说:“我想要平均指数值。”在你的情况下,[ 0 10 20 30 40]的平均值将为2。 - undefined
1
我认为只有楼主能够告诉我们他实际上在问什么。让我们等一下。 - undefined
显示剩余4条评论

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]

对于[[0 1],[0 1],[0 1]],得到输出[ 0.33333333 0.66666667]。OP要求按行计算平均值。这意味着输出应该包含3个值。只有OP能够澄清他的问题。 - undefined
1
[[0 5],[2 3],[4 1]] -> 输出 [ 0. 5. 2. 3. 4. 1.]。这里到底发生了什么? - undefined
@aerokite 很好的发现!我修正了我的错误:最后一行应该是rows而不是inverse(这就是为什么我首先计算rows的原因!)通过这个修正,你之前的例子的答案应该是:array([0., 2., 1., 1., 2., 0.]) - undefined

0
如果每个N个项目在每一列中都只出现1次(即每一列都是一个排名),你可以简单地执行以下操作:
#arr = np.array([['A','B'],['C','A'],['B','C']])

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

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