【问题标题】:Retrieving the average of averages in Python DataFrame检索 Python DataFrame 中的平均值
【发布时间】:2021-09-09 21:06:35
【问题描述】:

我有一个大众pandasDataFramedf

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

我的目标是每year 100 次采样 10 个数据点,并获得每年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 循环,但它会占用太多的运行时间。

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

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

我们将不胜感激。

【问题讨论】:

  • 你能发布一个我们可以复制和运行的示例 DataFrame 吗?
  • 你为什么要给count分配一个随机符号?

标签: python pandas dataframe mean standard-deviation


【解决方案1】:

试试:

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)

【讨论】:

  • 你的答案看起来肯定比我的干净,但我想知道为什么total_sd 列的值一直比我的高?据我所知,我们的方法似乎相同,我们样本数据的唯一区别是我们每年选择的观察次数
  • @DerekO 我重新阅读了 OP 的问题,但我计算的平均值是错误的 - OP 想要计算 100 个平均值,然后从 100 个平均值中计算平均值。我改变了我的功能,现在看起来很相似。
  • 啊,现在说得通了。希望我们的两个答案都能帮助 OP!
【解决方案2】:

我认为您可以一起使用 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

【讨论】:

    猜你喜欢
    • 2021-12-24
    • 2018-07-21
    • 2021-07-30
    • 2016-12-25
    • 1970-01-01
    • 2019-05-02
    • 2020-11-14
    • 2018-07-11
    • 2014-07-01
    相关资源
    最近更新 更多