如何找到Python列表中所有数字之间差值的平均值

20
我有一个像这样的Python列表,
arr = [110, 60, 30, 10, 5] 

我需要做的是找到所有数字与其他数字间的差异,再计算这些差值的平均数。
因此,在此例中,它首先会找到110与其余元素之间的差异,即60, 30, 10, 5,然后会找到60与其余元素之间的差异,即30, 10, 5,以此类推。
然后,计算所有这些差异的平均值。
现在,这可以通过两个For循环来轻松完成,但时间复杂度为O(n^2),并且代码有点“混乱”。 我想知道是否有更快,更有效的方法来执行相同的操作?

2
输入是否保证按降序排序?如果没有,您是要求绝对差的平均值,还是在计算差异时始终要从后面的元素减去前面的元素? - user2357112
@user2357112 对于我的情况,数字将按降序排序。然而,我认为通用的解决方法也可以计算出来,并且可能对人们有所帮助。 - Asad Hussain
3个回答

36

我先给出公式:

n = len(arr)
out = np.sum(arr * np.arange(n-1, -n, -2) ) / (n*(n-1) / 2)
# 52

解释:您想找到平均值的

a[0] - a[1], a[0] - a[2],..., a[0] - a[n-1]
             a[1] - a[2],..., a[1] - a[n-1]
                         ...

那里,你的

`a[0]` occurs `n-1` times with `+` sign, `0` with `-` -> `n-1` times
`a[1]` occurs `n-2` times with `+` sign, `1` with `-` -> `n-3` times
... and so on 

6
Python的基本等效代码是out = sum(x*j for x, j in zip(arr, range(n-1, -n, -2)))/(n*(n-1)/2) - J.G.
为了完整起见,n*(n-1)/2是(n选2),即配对数量。 - qwr

8

虽然不如@QuangHoang的答案那么出色,但这个答案使用了numpy广播来计算差异矩阵,然后平均上三角的值来得到答案。

import numpy as np

a = np.array([110, 60, 30, 10, 5])

dif = np.triu(a.reshape(len(a),-1) - a)
out = np.mean(dif[dif != 0])
52.0

5
现在,这可以很容易地用两个for循环完成,但时间复杂度为O(n^2),而且代码有点混乱。代码不需要混乱。
from statistics import mean

arr = [110, 60, 30, 10, 5]

m = mean(arr[i] - arr[j] for i in range(len(arr)) for j in range(i+1, len(arr)))

print(m)
# 52

如果数组未排序,则将arr [i] - arr [j]替换为abs(arr [i] - arr [j])

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