如何检查按索引分组的列上数据的正态性

问题描述 投票:0回答:1

我正在研究一个数据集,它表示某些流程中执行的某些活动的完成时间。只有 6 种类型的活动在整个数据集中重复出现,并由数值描述。示例数据集如下:

name duration
1    10
2    12
3    34
4    89
5    44
6    23
1    15
2    12
3    39
4    67
5    47
6    13

我正在尝试使用以下代码检查活动的持续时间是否呈正态分布:

import numpy as np
import pylab
import scipy.stats as stats
import seaborn as sns
from scipy.stats import normaltest

measurements = df['duration']
stats.probplot(measurements, dist='norm', plot=pylab)
pylab.show()
ax = sns.distplot(measurements)
stat,p = normaltest(measurements)

print('stat=%.3f, p=%.3f\n' % (stat, p))
if p > 0.05:
  print('probably gaussian')
else:
  print('probably non gaussian')

但我想对每种类型的活动执行此操作,这意味着将 stats.probplot()、sns.distplot() 和 normaltest() 应用于每组活动(例如,检查所有名为 1 的活动是否都有持续时间呈正态分布)。

关于如何在函数中指定为每组活动返回不同的图有什么想法吗?

pandas matplotlib statistics histogram
1个回答
1
投票

假设每个活动至少有 8 个样本(如果不这样做,

normaltest
将抛出错误),那么您可以根据唯一的活动值循环访问数据。您必须将
pylab.show
放在每个图表的末尾,这样它们就不会相互添加:

import numpy as np
import pandas as pd
import pylab
import scipy.stats as stats
import seaborn as sns

import random                        # Only needed by me to create a mock dataframe
import warnings                      # "distplot" is deprecated. Look into using "displot"... in the meantime
warnings.filterwarnings('ignore')    # I got sick of seeing the warning so I muted it

name = [1,2,3,4,5,6]*8
duration = [random.choice(range(0,100)) for _ in range(8*6)]
df = pd.DataFrame({"name":name, "duration":duration})

for name in df.name.unique():
    nameDF = df[df.name.eq(name)]
    measurements = nameDF['duration']
    stats.probplot(measurements, dist='norm', plot=pylab)
    pylab.show()
    ax = sns.distplot(measurements)
    ax.set_title(f'Name: {name}')
    pylab.show()
    
    stat,p = normaltest(measurements)
    print('stat=%.3f, p=%.3f\n' % (stat, p))
    if p > 0.05:
        print('probably gaussian')
    else:
        print('probably non gaussian')

enter image description here enter image description here

.
.
.
等等

© www.soinside.com 2019 - 2024. All rights reserved.