在 DataFrame 的行和列之间迭代以计算平均值

Iteration between rows and columsn of a DataFrame to calculate the mean

我有一个数据框,上面写着:

       A  2007/Ago  2007/Set  2007/Out ... 2020/Jan 2020/Fev
row1   x   number     number    number ...   number   number
row2   y   number     number    number ...   number   number
row3   w   number     number    number ...   number   number
...      
row27  z   number     number    number ...   number   number

我的意思是,每个单元格中都有数字。我想计算列以 2007 开头的单元格的平均值,然后计算列以 2008 开头的单元格的平均值,然后是 2009 年,...,然后是 2020 年,并对每一行执行此操作.

我试着画的是这样的:

x = []

for i in df.row(i):             #that is, for each row of the dataframe
    if column.startswith('j'):  #which starts with j=2008, 2009, 2010 etc
        x += df[i][j]         #the variable x gets the number on that row i,column j and sum

最后我要的是各种columsn各年的均值结果,也就是我要

result1       result2          result3     ...     resultn
mean colums   mean colums    mean columsn        mean columsn
 starts          starts        starts               starts
 with 2008      with 2009      with 2010          with 2020

也就是说,我想要 13 个新列:每个均值一个(从 2008 年到 2020 年)。

我无法继续这个循环,我不知道这有多基础,但我的问题是:

1- 有没有更好的方法来做到这一点?我的意思是,使用 pandas 函数而不是循环?

在我的数据框中,每个单元格对应于该月的总健康费用,我想取全年费用的平均值将其与每个城市的人口进行比较(这是 thw行)。我为此苦苦挣扎了一段时间,但无法解决。我使用pandas的水平很基础。

PS:对于数据帧表示,我不知道如何在 Whosebug 的正文问题中正确地写一个。

您可以遍历这些年,select 列的子集,然后使用 pandas' mean() 函数来获取那一年的平均值:

means = {}
for year in range(2007, 2021):
    # assuming df is your dataframe
    sub_df = df.loc[:, df.columns.str.startswith(str(year))]
    # first mean() aggregates per column, second mean() aggregates the whoöe year
    means[year] = sub_df.mean().mean()

这会产生一个 dict,其中年份作为键,那一年的平均值作为值。如果一年没有列,则表示 [year] 包含 NaN。

假设你有这个数据框:

       A  2007/Ago  2007/Set  2007/Out  2020/Jan  2020/Fev
row1   x         1         5         9        13        17
row2   y         2         6        10        14        18
row3   w         3         7        11        15        19
row27  z         4         8        12        16        20

您可以使用 .filter().mean(axis=1) 来计算值:

df["result"] = df.filter(regex=r"^\d{4}").mean(axis=1)
print(df)

打印:

       A  2007/Ago  2007/Set  2007/Out  2020/Jan  2020/Fev  result
row1   x         1         5         9        13        17     9.0
row2   y         2         6        10        14        18    10.0
row3   w         3         7        11        15        19    11.0
row27  z         4         8        12        16        20    12.0

通过 melt + pivot_table 的选项,aggfunc 设置为:

import pandas as pd

df = pd.DataFrame({
    'A': {'row1': 'x', 'row2': 'y', 'row3': 'w', 'row27': 'z'},
    '2007/Ago': {'row1': 1, 'row2': 2, 'row3': 3, 'row27': 4},
    '2007/Set': {'row1': 5, 'row2': 6, 'row3': 7, 'row27': 8},
    '2007/Out': {'row1': 9, 'row2': 10, 'row3': 11, 'row27': 12},
    '2020/Jan': {'row1': 13, 'row2': 14, 'row3': 15, 'row27': 16},
    '2020/Fev': {'row1': 17, 'row2': 18, 'row3': 19, 'row27': 20}
})

df = df.melt(id_vars='A', var_name='year')
# Rename month columns to their year value
df['year'] = df['year'].str.split('/').str[0]

# pivot to wide format based on the new year value
df = (
    df.pivot_table(columns='year', index='A', aggfunc='mean')
    .droplevel(0, 1)
    .rename_axis(None)
    .rename_axis(None, axis=1)
)
print(df)

df:

   2007  2020
w     7    17
x     5    15
y     6    16
z     8    18

在修改我的另一个答案时,我发现了这个单行:

df.mean().groupby(lambda x: x[:4]).mean()

说明

Pandas' `mean' 函数计算每列的平均值:

# using the DataFrame from Henry's answer:
df = pd.DataFrame({
    'A': {'row1': 'x', 'row2': 'y', 'row3': 'w', 'row27': 'z'},
    '2007/Ago': {'row1': 1, 'row2': 2, 'row3': 3, 'row27': 4},
    '2007/Set': {'row1': 5, 'row2': 6, 'row3': 7, 'row27': 8},
    '2007/Out': {'row1': 9, 'row2': 10, 'row3': 11, 'row27': 12},
    '2020/Jan': {'row1': 13, 'row2': 14, 'row3': 15, 'row27': 16},
    '2020/Fev': {'row1': 17, 'row2': 18, 'row3': 19, 'row27': 20}
})

# calculate mean per column
col_means = df.mean()
# 2007/Ago     2.5
# 2007/Set     6.5
# 2007/Out    10.5
# 2020/Jan    14.5
# 2020/Fev    18.5
# dtype: float64

# group above columns by first 4 characters, i.e., the year
year_groups = col_means.groupby(lambda x: x[:4])

# calculate the mean per year group
year_groups.mean()
# 2007     6.5
# 2020    16.5
# dtype: float64