如果我有这样的一个列表:
results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
我想在Python中计算此列表的方差,即平均值与平均数的差异的平方。
我该怎么做?访问列表中的元素进行计算对我来说很困惑,因为要获取平方差。
如果我有这样的一个列表:
results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
我想在Python中计算此列表的方差,即平均值与平均数的差异的平方。
我该怎么做?访问列表中的元素进行计算对我来说很困惑,因为要获取平方差。
var
:import numpy as np
results = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
print(np.var(results))
这将给你28.822364260579157
如果由于任何原因您不能使用numpy
,或者您不想使用内置函数来计算它,您还可以使用例如列表理解手动计算:
# calculate mean
m = sum(results) / len(results)
# calculate variance using a list comprehension
var_res = sum((xi - m) ** 2 for xi in results) / len(results)
这将为您提供相同的结果。
如果您对标准偏差感兴趣,您可以使用numpy.std:
print(np.std(results))
5.36864640860051
@Serge Ballesta讲得非常好,方差n
和n-1
之间的区别。在numpy中,您可以使用选项ddof
轻松设置此参数;其默认值为0
,因此对于n-1
情况,您只需执行以下操作:
np.var(results, ddof=1)
“手动”解决方案在@Serge Ballesta的回答中给出。
这两种方法都得到了32.024849178421285
。
您也可以为std
设置参数:
np.std(results, ddof=1)
5.659050201086865
ddof
的作用(请参见我的答案的后半部分和我链接到的答案)。 - Cleb从Python 3.4开始,标准库中带有方差
函数(样本方差或方差 n-1),作为统计
模块的一部分:
from statistics import variance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
variance(data)
# 32.024849178421285
使用 pvariance
函数可以获取总体方差(或样本方差):
from statistics import pvariance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
pvariance(data)
# 28.822364260579157
还要注意,如果你已经知道列表的平均值,那么 variance
和 pvariance
函数会接受第二个参数(分别为 xbar
和 mu
),以避免重新计算样本的平均值(这是方差计算的一部分)。
有两种方法定义方差。当你拥有完整数据集时,使用方差n,当你只有样本数据时,使用方差n-1。
两者之间的区别在于值m = sum(xi) / n
是否是真实平均值,还是仅仅是平均值的估计。
例如1:你想知道一个班级学生的平均身高和方差:好的,值m = sum(xi) / n
是真实平均值,Cleb给出的公式是正确的(方差n)。
例如2:你想知道公交车在车站经过的平均小时数和方差。你记录了一个月的时间,并获得了30个值。这时,值m = sum(xi) / n
仅是平均值的估计,随着更多的值,这个估计将更加准确。在这种情况下,实际方差的最佳估计是方差n-1。
varRes = sum([(xi - m)**2 for xi in results]) / (len(results) -1)
好的,这与Python无关,但它确实对统计分析产生影响,而问题被标记为统计学和方差
注意:通常,像numpy这样的统计库将方差n用于他们称之为var
或variance
的函数,并将方差n-1用于给出标准偏差的函数。
results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
import numpy as np
print 'numpy variance: ', np.var(results)
# without numpy by hand
# there are two ways of calculating the variance
# - 1. direct as central 2nd order moment (https://en.wikipedia.org/wiki/Moment_(mathematics))divided by the length of the vector
# - 2. "mean of square minus square of mean" (see https://en.wikipedia.org/wiki/Variance)
# calculate mean
n= len(results)
sum=0
for i in range(n):
sum = sum+ results[i]
mean=sum/n
print 'mean: ', mean
# calculate the central moment
sum2=0
for i in range(n):
sum2=sum2+ (results[i]-mean)**2
myvar1=sum2/n
print "my variance1: ", myvar1
# calculate the mean of square minus square of mean
sum3=0
for i in range(n):
sum3=sum3+ results[i]**2
myvar2 = sum3/n - mean**2
print "my variance2: ", myvar2
numpy variance: 28.8223642606
mean: -3.731599805
my variance1: 28.8223642606
my variance2: 28.8223642606
import numpy as np
def get_variance(xs):
mean = np.mean(xs)
summed = 0
for x in xs:
summed += (x - mean)**2
return summed / (len(xs))
print(get_variance([1,2,3,4,5]))
out 2.0
a = [1,2,3,4,5]
variance = np.var(a, ddof=1)
print(variance)
import math
def get_mean_var(results):
# calculate mean
mean = round(sum(results) / len(results), 2)
# calculate variance using a list comprehension
var = round(sum((xi - mean) ** 2 for xi in results) / len(results), 2)
return mean, var
使用方法
get_mean_var([1,3,34])
math.sqrt
。你提供的是标准差。 - Gqqnbigmean = sum(vac_nums)/len(vac_nums);
count=0;
for i in range(len(vac_nums)):
variance = (vac_nums[i]-mean)**2;
count += variance;
print (count/len(vac_nums));
正确的答案是使用像NumPy这样的包,但如果您想自己编写代码,并且想要逐步实现,那么有一个具有更高准确性的好算法。请参见此链接https://www.johndcook.com/blog/standard_deviation/
我将我的Perl实现移植到Python。请在评论中指出问题。
Mklast = 0
Mk = 0
Sk = 0
k = 0
for xi in results:
k = k +1
Mk = Mklast + (xi - Mklast) / k
Sk = Sk + (xi - Mklast) * ( xi - Mk)
Mklast = Mk
var = Sk / (k -1)
print var
答案是
>>> print var
32.0248491784
如果没有导入任何模块,我会使用以下的Python3脚本:
#!/usr/bin/env python3
def createData():
data1=[12,54,60,3,15,6,36]
data2=[1,2,3,4,5]
data3=[100,30000,1567,3467,20000,23457,400,1,15]
dataset=[]
dataset.append(data1)
dataset.append(data2)
dataset.append(data3)
return dataset
def calculateMean(data):
means=[]
# one list of the nested list
for oneDataset in data:
sum=0
mean=0
# one datapoint in one inner list
for number in oneDataset:
# summing up
sum+=number
# mean for one inner list
mean=sum/len(oneDataset)
# adding a tuples of the original data and their mean to
# a list of tuples
item=(oneDataset, mean)
means.append(item)
return means
# to do: substract mean from each element and square the result
# sum up the square results and divide by number of elements
def calculateVariance(meanData):
variances=[]
# meanData is the list of tuples
# pair is one tuple
for pair in meanData:
# pair[0] is the original data
interResult=0
squareSum=0
for element in pair[0]:
interResult=(element-pair[1])**2
squareSum+=interResult
variance=squareSum/len(pair[0])
variances.append((pair[0], pair[1], variance))
return variances
def main():
my_data=createData()
my_means=calculateMean(my_data)
my_variances=calculateVariance(my_means)
print(my_variances)
if __name__ == "__main__":
main()
在这里,您可以获得原始数据、它们的平均值和方差的打印。我知道这种方法涵盖了多个数据集的列表,但我认为您可以快速适应它以满足您的目的 ;)