我有一个元组列表[(val1,freq1),(val2,freq2)....(valn,freqn)]。我需要测量上述数据的中心趋势(均值,中位数)和偏差度量(方差,均值)。我还想绘制值的箱线图。
我看到numpy数组有直接的方法来从值列表中获得均值/中值和标准差(或方差)。
numpy(或任何其他知名图书馆)是否有直接的手段在这样的频率分配表上运作?
另外,将上面的元组列表以编程方式扩展到一个列表的最佳方法是什么? (例如,如果freq dist是[(1,3),(50,2)],最好的方法是获得列表[1,1,1,50,50]来使用np.mean([1,1,1, 50,50]))
我看到自定义函数here,但我想尽可能使用标准实现
答案 0 :(得分:5)
首先,我将这个杂乱的列表更改为两个numpy
数组,如@ user8153:
val, freq = np.array(list_tuples).T
然后你可以重建数组(使用np.repeat
阻止循环):
data = np.repeat(val, freq)
在data
数组上使用numpy
statistical functions。
如果这会导致内存错误(或者您只想尽可能多地挤出性能),您还可以使用一些专用功能:
def mean_(val, freq):
return np.average(val, weights = freq)
def median_(val, freq):
ord = np.argsort(val)
cdf = np.cumsum(freq[ord])
return val[ord][np.searchsorted(cdf[-1] // 2, cdf)]
def mode_(val, freq): #in the strictest sense, assuming unique mode
return val[np.argmax(freq)]
def var_(val, freq):
avg = mean_(val, freq)
dev = freq * (val - avg) ** 2
return dev.sum() / (freq.sum() - 1)
def std_(val, freq):
return np.sqrt(var_(val, freq))
答案 1 :(得分:2)
将(值,频率)列表转换为值列表:
freqdist = [(1,3), (50,2)]
sum(([val,]*freq for val, freq in freqdist), [])
给出
[1, 1, 1, 50, 50]
要计算平均值,您可以使用np.average
取weights
参数来避免构建值列表:
vals, freqs = np.array(freqdist).T
np.average(vals, weights = freqs)
按照您的预期给出20.6。不过,我不认为这适用于均值,方差或标准偏差。
答案 2 :(得分:0)
import pandas as pd
import math
import numpy as np
频率分布数据
class freq
0 60-65 3
1 65-70 150
2 70-75 335
3 75-80 135
4 80-85 4
为类创建中间点列
df[['Upper','Lower']]=df['class'].str.split('-',expand=True)
df['Xi']=(df['Upper'].astype(float)+df['Lower'].astype(float))/2
df.drop(['Upper','Lower'],axis=1,inplace=True)
因此
class freq Xi
0 60-65 3 62.5
1 65-70 150 67.5
2 70-75 335 72.5
3 75-80 135 77.5
4 80-85 4 82.5
平均值
mean = np.average(df['Xi'], weights=df['freq'])
mean
72.396331738437
标准偏差
std = np.sqrt(np.average((df['Xi']-mean)**2,weights=df['freq']))
std
3.5311919641103877