在Python列表中顺序查找行的均值和中位数的最有效方法是什么?
例如,我的清单:
input_list = [1,2,4,6,7,8]
我想生成一个包含以下内容的输出列表:
output_list_mean = [1,1.5,2.3,3.25,4,4.7]
output_list_median = [1,1.5,2.0,3.0,4.0,5.0]
如果平均值计算如下:
中位数计算如下:
我试图用以下循环实现它,但它看起来非常低效。
import numpy
input_list = [1,2,4,6,7,8]
for item in range(1,len(input_list)+1):
print(numpy.mean(input_list[:item]))
print(numpy.median(input_list[:item]))
答案 0 :(得分:8)
你自己做的任何事情,特别是中位数,要么需要大量的工作,要么效率很低,但是Pandas带有你所追求的功能的内置高效实现,扩展的意思是O( n),使用跳过列表扩展中位数是O(n * log(n)):
import pandas as pd
import numpy as np
input_list = [1, 2, 4, 6, 7, 8]
>>> pd.expanding_mean(np.array(input_list))
array([ 1. , 1.5 , 2.33333, 3.25 , 4. , 4.66667])
>>> pd.expanding_median(np.array(input_list))
array([ 1. , 1.5, 2. , 3. , 4. , 5. ])
答案 1 :(得分:4)
您可以使用<input type="hidden" name="notify_url" value="http://site2.com/ipn.php"/>
对数组进行切片,并将itertools.islice
与np.fromiter
一起使用:
np.mean
作为替代方案,如果您想要平均值,可以使用np.cumsum
获取元素的累积总和,并使用>>> arr=np.array([1,2,4,6,7,8])
>>> l=arr.size
>>> from itertools import islice
>>> [np.fromiter(islice(arr,0,i+1),float).mean(dtype=np.float32) for i in xrange(l)]
[1.0, 1.5, 2.3333333, 3.25, 4.0, 4.6666665]
除以主数组:
np.true_divide
答案 2 :(得分:0)
import numpy as np
a = np.array([1,2,4,6,7,8])
使用numpy.meshgrid
(还有其他公式可行)和numpy.triu
创建一个包含您感兴趣的值的数组。
x, y = np.meshgrid(a,a)
# y = a.repeat(len(a)).reshape(len(a), len(a))
c = np.triu(y)
>>> y
array([[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[4, 4, 4, 4, 4, 4],
[6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8]])
>>> c
array([[1, 1, 1, 1, 1, 1],
[0, 2, 2, 2, 2, 2],
[0, 0, 4, 4, 4, 4],
[0, 0, 0, 6, 6, 6],
[0, 0, 0, 0, 7, 7],
[0, 0, 0, 0, 0, 8]])
定义一个函数,该函数返回所有非零值的中位数,并将其应用于有趣的数组。
def foo(a):
'''return the the median of the non-zero elements of a 1d array
'''
return np.median(a[a.nonzero()])
d = np.apply_along_axis(foo, 0, c)
>>> d
array([ 1. , 1.5, 2. , 3. , 4. , 5. ])
>>>