【问题标题】:Pandas dataframe fillna() only some columns in place熊猫数据框 fillna() 只有一些列到位
【发布时间】:2016-11-03 04:37:49
【问题描述】:

我试图在 Pandas 数据框中只为某些列子集填充 0 值。

当我这样做时:

import pandas as pd
df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]})
print df
df.fillna(value=0, inplace=True)
print df

输出:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  NaN  7.0
3  NaN  6.0  8.0
     a    b    c
0  1.0  4.0  0.0
1  2.0  5.0  0.0
2  3.0  0.0  7.0
3  0.0  6.0  8.0

它将每个None 替换为0。我想做的是,只替换ab列中的Nones,而不是c

最好的方法是什么?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以选择所需的列并通过分配来完成:

    df[['a', 'b']] = df[['a','b']].fillna(value=0)
    

    结果输出如预期:

         a    b    c
    0  1.0  4.0  NaN
    1  2.0  5.0  NaN
    2  3.0  0.0  7.0
    3  0.0  6.0  8.0
    

    【讨论】:

    • 是的,这正是我想要的!谢谢你。有什么方法可以就地做到这一点?我的原始数据框很大。
    • 我认为这样做不会有任何性能提升,因为无论如何您都在覆盖 orig df
    • 这里的 loc 是多余的,df[['a', 'b']] = df[['a','b']].fillna(value=0) 仍然可以工作
    • @EdChum 它不会产生一个临时数据帧,因此需要更多内存来这样做吗? (我更关心内存而不是时间复杂度。)
    • 对于许多操作,inplace 仍然可以处理副本。我不知道fillna 是不是这样。请参阅 Pandas 核心开发人员之一的this answer
    【解决方案2】:

    您可以使用 dictfillna 为不同的列使用不同的值

    df.fillna({'a':0,'b':0})
    Out[829]: 
         a    b    c
    0  1.0  4.0  NaN
    1  2.0  5.0  NaN
    2  3.0  0.0  7.0
    3  0.0  6.0  8.0
    

    分配回来后

    df=df.fillna({'a':0,'b':0})
    df
    Out[831]: 
         a    b    c
    0  1.0  4.0  NaN
    1  2.0  5.0  NaN
    2  3.0  0.0  7.0
    3  0.0  6.0  8.0
    

    【讨论】:

    • 真的很酷,顺便说一句,如果你愿意,你可以使用fromkeys,+1
    • 如果它实际上为不同的列显示不同的值,答案/示例会更清楚。
    • @RufusVS 是对的,但仍然尝试匹配操作的预期输出
    • 这是比公认答案更好的解决方案,因为它避免了链式索引问题,例如如果与df.fillna({'a':0,'b':0}, inplace=True) 一起使用
    • 如何在字典中使用ffillbfill等方法?
    【解决方案3】:

    您可以避免使用 Wen 的解决方案和 inplace=True 复制对象:

    df.fillna({'a':0, 'b':0}, inplace=True)
    print(df)
    

    产量:

         a    b    c
    0  1.0  4.0  NaN
    1  2.0  5.0  NaN
    2  3.0  0.0  7.0
    3  0.0  6.0  8.0
    

    【讨论】:

    【解决方案4】:

    使用最佳答案会产生有关更改 df 切片副本的警告。假设您有其他列,更好的方法是传递字典:
    df.fillna({'A': 'NA', 'B': 'NA'}, inplace=True)

    【讨论】:

      【解决方案5】:

      以下是您可以在一行中完成所有操作的方法:

      df[['a', 'b']].fillna(value=0, inplace=True)
      

      细分:df[['a', 'b']] 选择要为其填充 NaN 值的列,value=0 告诉它用零填充 NaN,inplace=True 将使更改永久化,而无需复制对象。

      【讨论】:

      • 不知何故这给了 SettingWithCopyWarning 并且更改未反映在df中。
      【解决方案6】:

      或者类似的东西:

      df.loc[df['a'].isnull(),'a']=0
      df.loc[df['b'].isnull(),'b']=0
      

      如果还有更多:

      for i in your_list:
          df.loc[df[i].isnull(),i]=0
      

      【讨论】:

        【解决方案7】:

        这应该可以工作并且没有复制警告

        df[['a', 'b']] = df.loc[:,['a', 'b']].fillna(value=0)
        

        【讨论】:

          【解决方案8】:

          由于某些奇怪的原因,这不起作用(使用 Pandas:'0.25.1')

          df[['col1', 'col2']].fillna(value=0, inplace=True)
          

          另一种解决方案:

          subset_cols = ['col1','col2']
          [df[col].fillna(0, inplace=True) for col in subset_cols]
          

          例子:

          df = pd.DataFrame(data={'col1':[1,2,np.nan,], 'col2':[1,np.nan,3], 'col3':[np.nan,2,3]})
          

          输出:

             col1  col2  col3
          0  1.00  1.00   nan
          1  2.00   nan  2.00
          2   nan  3.00  3.00
          

          应用列表组合。填充值:

          subset_cols = ['col1','col2']
          [df[col].fillna(0, inplace=True) for col in subset_cols]
          

          输出:

             col1  col2  col3
          0  1.00  1.00   nan
          1  2.00  0.00  2.00
          2  0.00  3.00  3.00
          

          【讨论】:

          • 我认为inplace 不是很好的做法,检查thisthis
          • 所以在我看来最好的应该是如果提出inplace警告然后从熊猫中删除。
          • 这么简单的建议 - 永远避免就地,永远不会出现这样的问题;)
          【解决方案9】:

          有时这种语法不起作用:

          df[['col1','col2']] = df[['col1','col2']].fillna()
          

          改用以下内容:

          df['col1','col2']
          

          【讨论】:

            猜你喜欢
            • 2017-01-04
            • 2020-06-03
            • 1970-01-01
            • 1970-01-01
            • 2015-06-28
            • 2020-02-13
            • 1970-01-01
            • 2016-11-16
            • 1970-01-01
            相关资源
            最近更新 更多