使用for循环处理多个pandas数据帧

问题描述 投票:0回答:1

我正在处理许多数据帧,并希望使用 for 循环删除空值和负值。 python 代码看起来应该可以工作,但事实并非如此。我想知道为什么这个逻辑在 python 中不起作用?

df1 = pd.DataFrame({'depth': [-1, 2, 3, 4, np.nan], 'temp': [-1,2,3,4,5]})
df2 = pd.DataFrame({'depth': [1, 2, 3, 4, 5],       'temp': [-1,2,3,4,5]})
df3 = pd.DataFrame({'depth': [1, 2, 3, 4, 5],       'temp': [-1,2,3,4,np.nan]})

df_names=(df1, df2, df3)

for i in df_names:
    i = i.dropna()
    i = i[i['temp']>0]
    i = i[i['depth']>0]

print(df1, '\n', df2,'\n', df3)

enter image description here

dataframe for-loop
1个回答
0
投票

您的代码不起作用的原因是您在 for 循环中使用了赋值操作。这会导致创建一个新变量

df

这就是它的工作原理:

  1. 让我们检查一下初始变量的存储位置:
df1 = pd.DataFrame({'depth': [-1, 2, 3, 4, np.nan], 'temp': [-1,2,3,4,5]})
df2 = pd.DataFrame({'depth': [1, 2, 3, 4, 5],       'temp': [-1,2,3,4,5]})
df3 = pd.DataFrame({'depth': [1, 2, 3, 4, 5],       'temp': [-1,2,3,4,np.nan]})

df_names=[df1, df2, df3]
print(id(df1), id(df_names[0]))

2495042353424 2495042353424

太棒了,

df1
和列表的0索引元素存储在内存的同一位置(这使得场景)。

  1. 然后让我们运行一个带有赋值操作的 for 循环,并检查我们是否仍在同一个对象上操作(我在这里稍微简化了您的代码):
for i in df_names:
    print(id(i))
    i = i.dropna()
    print('after assignment:', id(i))

2495042353424
after assignment: 2495042514512
2495042411984
after assignment: 2495042516048
2495006121552
after assignment: 2495042354768

在这里您可以看到,在分配操作之后,创建了一个新的临时对象

df
(在内存中的不同位置),并且您对其应用了所有操作(dropna,然后是数据帧过滤)!当 for 循环的每次迭代结束时,该对象将被简单地销毁,并且不会影响您的初始数据。

如何解决? 在这个特定的示例中,我可以建议您简单地避免赋值操作并使用数据框就地方法:

for df in df_names:
    df.dropna(inplace = True)
    df.drop(df[~(df['temp']>0)].index, inplace = True)
    df.drop(df[~(df['depth']>0)].index, inplace = True)
print(df1)

    depth   temp
1   2.0      2
2   3.0      3
3   4.0      4

© www.soinside.com 2019 - 2024. All rights reserved.