你能把它合并成一个 for 循环吗?

Can you consolidate this into a for loop?

我正在尝试将其合并为一个 for 循环。尝试为每个年龄段创建一个单独的数据框,对每个数据框进行排序,计算其中一列的平均值,并将数据框保存到 excel 文件

df21=df[~df['Age'].isin(['22','23','24','25'])]
df21=df21.sort_values(by='FPS/G',ascending=False)
mean21=df21["FPS/G"].mean()
df21.to_excel(writer, 'Age 21')

df22=df[~df['Age'].isin(['21','23','24','25'])]
df22=df22.sort_values(by='FPS/G',ascending=False)
mean22=df22["FPS/G"].mean()
df22.to_excel(writer, 'Age 22')

df23=df[~df['Age'].isin(['21','22','24','25'])]
df23=df23.sort_values(by='FPS/G',ascending=False)
mean23=df23["FPS/G"].mean()
df23.to_excel(writer, 'Age 23')

df24=df[~df['Age'].isin(['21','22','23','25'])]
df24=df24.sort_values(by='FPS/G',ascending=False)
mean24=df24["FPS/G"].mean()
df24.to_excel(writer, 'Age 24')

df25=df[~df['Age'].isin(['21','22','23','24'])]
df25=df25.sort_values(by='FPS/G',ascending=False)
mean25=df25["FPS/G"].mean()
df25.to_excel(writer, 'Age 25')

遍历年龄字符串列表。在过滤时使用它来为您写入 Excel 文件的特定年龄创建 df。并将方法放入以年龄为关键字的字典中,而不是单独的变量中。

ages = ['21', '22', '23', '24', '25']
means = {}

for age in ages:
    age_df = df[df['Age'] == age].sort_values(by='FPS/G',ascending=False)
    means[age] = age_df["FPS/G"].mean()
    age_df.to_excel(writer, f'Age {age}')

如何将重复代码转换为循环:

我们在迭代(循环)什么?

每次通过我们的流程,我们都会处理不同的可能年龄值。这些显然是字符串,选自 '21''22''23''24''25'.

过程中每次有什么不同?

  • 临时数据框的变量名;但这没关系——它们是暂时的;我们不关心 df21 等处理后的值,我们只关心写入文件。所以我们可以为此重用一个变量。

  • 平均值的变量名称。 We do not want 每次循环都尝试创建一个不同的变量——相反,我们将以某种数据结构收集数据。在这里,dict 是自然的选择。

  • 用于 to_excel 方法调用的标签。

  • 使用.isin筛选出的年龄。

每次都一样的是什么?

写出其中的 shell,使用注释和临时变量来标记步骤 1 中的部分。我们将为那些我们认为无关紧要的部分使用更通用的变量名称。我们现在还将编写 dict 逻辑。

这给了我们:

# First, we set up an empty dictionary for the means:
means = {}

# Each time through the loop, we will do something like:
age = # <-- we will need something that changes each time, representing
# the age we are currently processing.
other_ages = # ??? we need to base this off the `age` somehow.
age_df = df[~df['Age'].isin(other_ages)]
age_df = age_df.sort_values(by='FPS/G',ascending=False)
means[age] = age_df["FPS/G"].mean()
label = # ??? we need to base this off the `age` somehow.
age_df.to_excel(writer, label)

缺少什么逻辑?

  • age 只是我们的迭代变量,所以我们不需要分配它——我们将使用一个 for 循环,它会来自那个自动循环。我们会将可能的值放入一个元组(或列表)中,这很容易迭代。我们称之为 ages.

  • other_ages 需要是一个看起来像完整年龄列表的列表,但删除了 age。例如,我们可以通过制作 ages 的列表副本和 .removeing 值来获得它;或者我们可以使用列表理解来制作过滤副本(我将在此处展示的方法)。

  • label 需要是以 'Age ' 开头并以年龄字符串结尾的文本。我们可以使用字符串格式轻松创建它。

插入这些逻辑,我们得到最终结果:

means = {}
ages = ('21', '22', '23', '24', '25')
for age in ages:
    other_ages = [a for a in ages if a != age]
    age_df = df[~df['Age'].isin(other_ages)]
    age_df = age_df.sort_values(by='FPS/G',ascending=False)
    means[age] = age_df["FPS/G"].mean()
    label = f'Age {age}'
    age_df.to_excel(writer, label)

当然,如果我们愿意,我们可以放置新的临时计算 in-line:

means = {}
ages = ('21', '22', '23', '24', '25')
for age in ages:
    age_df = df[~df['Age'].isin([a for a in ages if a != age])]
    age_df = age_df.sort_values(by='FPS/G',ascending=False)
    means[age] = age_df["FPS/G"].mean()
    age_df.to_excel(writer, f'Age {age}')