检索 Python DataFrame 中的平均值

Retrieving the average of averages in Python DataFrame

我有一个质量pandas DataFrame df:

year          count
1983          5
1983          4
1983          7
...
2009          8
2009          11
2009          30

我的目标是每 year 采样 10 个数据点 100 次,并获得每年 count 的均值和标准差。 count 值的符号是随机确定的。


我想对每个 year 随机抽取 10 个数据,可以通过以下方式完成:

new_df = pd.DataFrame(columns=['year', 'count'])
ref = df.year.unique()

for i in range(len(ref)):
  appended_df = df[df['year'] == ref[i]].sample(n=10)
  new_df = pd.concat([new_df,appended_df])

然后,我随机给 count 分配一个符号(这样 count 可能是正数或负数)并将其重命名为 value,这是可以完成的通过:

vlist = []

for i in range(len(new_df)):
  if randint(0,1) == 0:
    vlist.append(new_df.count.iloc[i])
  else:
    vlist.append(new_df.count.iloc[i] * -1)

new_data['value'] = vlist

获得每个 year 的均值和标准差非常简单:

xdf = new_data.groupby("year").agg([np.mean, np.std]).reset_index()

但我似乎找不到一种最佳方法来尝试每个 year 进行 100 次采样,存储平均值,并获取每年这 100 个平均值的平均值和标准差。我可以考虑使用 for 循环,但它会占用太多运行时间。

基本上,输出应该是下面的形式(这里的 value 是任意的):

year      mean_of_100_means  total_sd
1983      4.22               0.43
1984      -6.39              1.25
1985      2.01               0.04
...
2007      11.92              3.38
2008      -5.27              1.67
2009      1.85               0.99

如有任何见解,我们将不胜感激。

我认为您可以同时使用 pandas groupbysample 函数从您的 DataFrame 的每年中抽取 10 个样本。如果你把它放在一个循环中,那么你可以对其采样 100 次,然后合并结果。

听起来你只需要100个均值的标准差(你不需要10个观察样本的标准差),所以你可以只计算你的groupby和sample中的均值,然后当您创建最终 DataFrame 的 total_sd 列时,计算这 100 个平均值中的每一个的标准偏差。

import numpy as np
import pandas as pd

np.random.seed(42)

## create a random DataFrame with 100 entries for the years 1980-1999, length 2000
df = pd.DataFrame({
    'year':[year for year in list(range(1980, 2000)) for _ in range(100)],
    'count':np.random.randint(1,100,size=2000)
})

list_of_means = []

## sample 10 observations from each year, and repeat this process 100 times, storing the mean for each year in a list
for _ in range(100):
    df_sample = df.groupby("year").sample(10).groupby("year").mean()
    list_of_means.append(df_sample['count'].tolist())
array_of_means = [np.array(x) for x in list_of_means]

result = pd.DataFrame({
    'year': df.year.unique(),
    'mean_of_100_means': [np.mean(k) for k in zip(*array_of_means)],
    'total_sd': [np.std(k) for k in zip(*array_of_means)]
})

这导致:

>>> result
    year  mean_of_100_means  total_sd
0   1980             50.316  8.656948
1   1981             48.274  8.647643
2   1982             47.958  8.598455
3   1983             49.357  7.854620
4   1984             48.977  8.523484
5   1985             49.847  7.114485
6   1986             47.338  8.220143
7   1987             48.106  9.413085
8   1988             53.487  9.237561
9   1989             47.376  9.173845
10  1990             46.141  9.061634
11  1991             46.851  7.647189
12  1992             49.389  7.743318
13  1993             52.207  9.333309
14  1994             47.271  8.177815
15  1995             52.555  8.377355
16  1996             47.606  8.668769
17  1997             52.584  8.200558
18  1998             51.993  8.695232
19  1999             49.054  8.178929

尝试:

def fn(x):
    _100_means = [x.sample(10).mean() for i in range(100)]
    return {
        "mean_of_100_means": np.mean(_100_means),
        "total_sd": np.std(_100_means),
    }


print(df.groupby("year")["count"].apply(fn).unstack().reset_index())

编辑:更改了平均值的计算。

打印:

    year  mean_of_100_means   total_sd
0   1983             48.986   8.330787
1   1984             48.479  10.384896
2   1985             48.957   7.854900
3   1986             50.821  10.303847
4   1987             50.198   9.835832
5   1988             47.497   8.678749
6   1989             46.763   9.197387
7   1990             49.696   8.837589
8   1991             46.979   8.141969
9   1992             48.555   8.603597
10  1993             50.220   8.263946
11  1994             48.735   9.954741
12  1995             49.759   8.532844
13  1996             49.832   8.998654
14  1997             50.306   9.038316
15  1998             49.513   9.024341
16  1999             50.532   9.883166
17  2000             49.195   9.177008
18  2001             50.731   8.309244
19  2002             48.792   9.680028
20  2003             50.251   9.384759
21  2004             50.522   9.269677
22  2005             48.090   8.964458
23  2006             49.529   8.250701
24  2007             47.192   8.682196
25  2008             50.124   9.337356
26  2009             47.988   8.053438

数据框已创建:

data = []
for y in range(1983, 2010):
    for i in np.random.randint(0, 100, size=1000):
        data.append({"year": y, "count": i})
df = pd.DataFrame(data)