【问题标题】:How to solve the issue of filling all the values with None?如何解决用 None 填充所有值的问题?
【发布时间】:2020-11-10 19:18:54
【问题描述】:

我正在尝试填充数据框中的缺失值,但所有值都被替换为None

这是我尝试过的示例:

# Basic libraries
import os
import pandas as pd
import numpy as np

# Visualization libraries
import matplotlib.pyplot as plt
import seaborn as sns
import folium
#import folium.plugins as plugins
from wordcloud import WordCloud
import plotly.express as px

data_dict = {'First':[100, 90, np.nan, 95], 
        'Second': [30, 45, 56, np.nan], 
        'Third':[np.nan, 40, 80, 98]} 
  
#reating a dataframe from list 
df1 = pd.DataFrame(data_dict)

#first_try_with_column_name
df1.loc[:,'First'] = df1.loc[:,'First'].fillna(method='ffill', inplace=True)

#Second_try_Using_List_of_Columns
list_columns = ['First','Second','Third']
df1.loc[:,list_columns] = df1.loc[:,list_columns].fillna(value, inplace=True)
df1

如图所示,我用了多种方式来理解这个问题背后的原因,所以我尝试使用列名,然后我使用了列名列表,但不幸的是,问题是一样的。

请问有什么推荐的吗?

【问题讨论】:

  • 您已经在原地指定,您不需要再次分配该值。那可能是个问题。 df1.loc[:,list_columns].fillna(value, inplace=True) 应该足够了。
  • 请不要这样写代码!只需直接访问该列df1['First'] = df1['First'].fillna(method='ffill') 或更好:df1['First'] = df1['First'].ffill()。作为一般经验法则,如果您确实需要,请仅使用inplace=True。如果您经常使用inplace=True,将来您可能会遇到一些无法预料的问题,可能不是这段代码,而是其他代码。
  • 如果您使用多列,loc 很好。你也可以df[list_columns] = df[list_columns].fillna()
  • @DavidErickson 感谢您的评论。但是,最后一个命令 df[list_columns] = df[list_columns].fillna() 没有成功运行,问题仍然存在。另外,我有兴趣使用inplace=True。那么,还有其他推荐吗?

标签: python python-3.x pandas dataframe missing-data


【解决方案1】:

改变

df1.loc[:,'First'] = df1.loc[:,'First'].fillna(method='ffill', inplace=True)

df1.loc[:,'First'].fillna(method='ffill', inplace=True)

这是因为您使用的是 inplace=True,这意味着将对原始数据框进行更改。

至于 None 值,它们来自返回 None 的函数,因为它是就地的并且没有什么可以返回。因此,所有值都变为无。


对于每一列,

for col in df1.columns:
    df1[col].fillna(10, inplace=True)
df1

PS:对于未来的用户,--避免就地,因为In pandas, is inplace = True considered harmful, or not?

【讨论】:

  • 感谢您的评论。它运行良好,但我真的有兴趣为列列表填充缺失的数据吗?
  • 非常感谢。这是一个很好的解决方案。 :)
【解决方案2】:

如果你想转发填充,你可以这样做:

df1 = df1.ffill()

这会导致:

    First   Second  Third
0   100.0   30.0    NaN
1   90.0    45.0    40.0
2   90.0    56.0    80.0
3   95.0    56.0    98.0

还有一个 nan 值,所以我们仍然可以进行回填:

df1 = df1.bfill()

最终结果:

    First   Second  Third
0   100.0   30.0    40.0
1   90.0    45.0    40.0
2   90.0    56.0    80.0
3   95.0    56.0    98.0

如果您只想在特定列中转发填充 na,请使用以下内容。请注意我没有使用inplace=True。这就是为什么您的代码以前无法正常工作的原因。

columns_to_fillna = ['Second', 'Third']
df1.loc[:, columns_to_fillna] = df1.loc[:, columns_to_fillna].ffill()

如果你真的想使用inplace=True,这是不建议的,那么:

columns_to_fillna = ['Second', 'Third']
df1.loc[:, columns_to_fillna].ffill(inplace=True)

不建议使用 inplace 的原因,在此讨论:
https://stackoverflow.com/a/60020384/6366770

【讨论】:

  • 感谢您的评论。它工作得很好,但是如何填充特定列中的缺失值呢?
  • 非常感谢您的帮助。但是,真的,我需要使用inplace=True,因为我需要将效果直接反映到数据框中。我可以使用您的解决方案,但我需要一个额外的命令来将这些更改反映到原始数据框。如果有这样的解决方案我会为你考虑的。
  • @QaddomiObaid 请参阅这个答案,了解为什么你应该尽量避免inplace=True:stackoverflow.com/a/60020384/6366770
  • Thx @DavidErickson 我再次更新了我的答案,使用你的 cmets :)
  • @DavidErickson 非常感谢。我阅读了附加的链接,现在我明白了这个问题。但是,是否有这样的技巧来反映对原始数据框的更改而不是使用inplace=True?也许喜欢使用副本?我确实需要更改才能对主数据框生效,因为后续将对主数据框进行大量更改。我是初学者,我需要专家的推荐。
猜你喜欢
  • 1970-01-01
  • 2012-11-06
  • 2021-11-05
  • 2010-11-15
  • 1970-01-01
  • 2022-10-07
  • 2010-11-28
  • 2013-11-25
  • 2013-01-11
相关资源
最近更新 更多