我正在处理许多数据帧,并希望使用 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)
您的代码不起作用的原因是您在 for 循环中使用了赋值操作。这会导致创建一个新变量
df
。
这就是它的工作原理:
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索引元素存储在内存的同一位置(这使得场景)。
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