【问题标题】:'For loop' isn't creating modified copies of existing dataframes“For循环”没有创建现有数据帧的修改副本
【发布时间】:2020-10-31 05:16:40
【问题描述】:

我想使用我在 Jupyter 笔记本中加载的新名称(在此示例中为 df1_mdf2_m 等)创建数据帧的修改副本(仅包含某些列的副本)。但是由于某种原因,当我尝试使用新名称打印副本 dfs 时,以下代码会生成空表。当我尝试使用循环内的代码自行执行此操作时,它可以工作。因此,出于某种原因,将此代码放在 for 循环中会导致出现问题。可能出了什么问题?

这是不起作用/产生空 dfs 的“for 循环”代码:

parameter_cols = [col1, col2, col3]

df1_m = pd.DataFrame()
df2_m = pd.DataFrame()
df3_m = pd.DataFrame()
df4_m = pd.DataFrame()
df5_m = pd.DataFrame()
df6_m = pd.DataFrame()

df_list = [df1, df2, df3, df4, df5, df6]
df_m_list = [df1_m, df2_m, df3_m, df4_m, df5_m, df6_m]
year_list = [2015, 2016, 2017, 2018, 2019, 2020]

for df, df_m, yr in zip(df_list, df_m_list, year_list):
    df_m = df[parameter_cols]
    df_m = df_m.assign(year = yr)

但是循环外的相同代码可以工作并生成所需的副本 df (df1_m):

df1_m = df1[parameter_cols]
df1_m = df1_m.assign(year=2015)

这是为什么?

【问题讨论】:

  • 虽然这看起来总体上是一个非常糟糕的主意,但您可能正在尝试在 range(len(df_list)) 上使用 for 循环或类似的东西,并通过循环内的索引引用您的列表。您现在拥有它的方式是创建一个名为 df_m 的新 df 并反复覆盖它。
  • @Chris 即使有很多数据框,最好的做法是在没有循环的情况下单独使用它们?你说这是一个坏主意,但我认为尽可能压缩代码是更好的代码实践

标签: python pandas dataframe for-loop


【解决方案1】:

df_m = df[parameter_cols] 只是更改本地指针,而不是引用的变量。这会做的事情:

for i, yr in enumerate(year_list):
    df_m = df_list[i][parameter_cols]
    df_m_list[i] = df_m.assign(year = yr)

【讨论】:

  • 循环中的df_m_list[i] 似乎没有将[i] 列表元素分配为数据帧副本的新名称。例如,如果我打印df1_m,它仍然是空的。如果我用 x 替换 df_m_list[i] 并打印它,它会打印最后一个迭代的表。
【解决方案2】:

您的设置似乎有点矫枉过正。你可以忘记df1_m,....因为df.assign默认创建一个副本,你可以这样做:

parameter_cols = [col1, col2, col3]
df_list = [df1, df2, df3, df4, df5, df6]
year_list = [2015, 2016, 2017, 2018, 2019, 2020]

df_m_list = [d[parameter_cols].assign(year=y) 
                for d, y in zip(df_list, year_list)
            ]

【讨论】:

  • 这个想法是为新副本分配某些名称,这就是为什么有一个 df_m_list。在建议的列表理解中,有没有办法将每次迭代分配给现有列表中的某个名称(在我的示例中,名称为 df1_m、df2_m 的 df_m_list)?
猜你喜欢
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
相关资源
最近更新 更多