【问题标题】:How to replace None only with empty string using pandas?如何使用 pandas 仅用空字符串替换 None?
【发布时间】:2015-07-08 14:31:16
【问题描述】:

下面的代码生成一个df

import pandas as pd
from datetime import datetime as dt
import numpy as np

dates = [dt(2014, 1, 2, 2), dt(2014, 1, 2, 3), dt(2014, 1, 2, 4), None]
strings1 = ['A', 'B',None, 'C']
strings2 = [None, 'B','C', 'C']
strings3 = ['A', 'B','C', None]
vals = [1.,2.,np.nan, 4.]
df = pd.DataFrame(dict(zip(['A','B','C','D','E'],
                           [strings1, dates, strings2, strings3, vals])))



+---+------+---------------------+------+------+-----+
|   |  A   |          B          |  C   |  D   |  E  |
+---+------+---------------------+------+------+-----+
| 0 | A    | 2014-01-02 02:00:00 | None | A    | 1   |
| 1 | B    | 2014-01-02 03:00:00 | B    | B    | 2   |
| 2 | None | 2014-01-02 04:00:00 | C    | C    | NaN |
| 3 | C    | NaT                 | C    | None | 4   |
+---+------+---------------------+------+------+-----+

我想用''(空字符串)替换所有None(python中的真正None,而不是str)。

预期 df

+---+---+---------------------+---+---+-----+
|   | A |          B          | C | D |  E  |
+---+---+---------------------+---+---+-----+
| 0 | A | 2014-01-02 02:00:00 |   | A | 1   |
| 1 | B | 2014-01-02 03:00:00 | B | B | 2   |
| 2 |   | 2014-01-02 04:00:00 | C | C | NaN |
| 3 | C | NaT                 | C |   | 4   |
+---+---+---------------------+---+---+-----+

我做的是

df = df.replace([None], [''], regex=True)

但我得到了

+---+---+---------------------+---+------+---+
|   | A |          B          | C |  D   | E |
+---+---+---------------------+---+------+---+
| 0 | A | 1388628000000000000 |   | A    | 1 |
| 1 | B | 1388631600000000000 | B | B    | 2 |
| 2 |   | 1388635200000000000 | C | C    |   |
| 3 | C |                     | C |      | 4 |
+---+---+---------------------+---+------+---+

  1. 所有日期都变成大数字
  2. NaTNaN 都被替换了,我不希望这样。

我怎样才能正确有效地做到这一点?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这就够了

    df.fillna("",inplace=True)
    
    df
    Out[142]: 
       A                    B  C  D  E
    0  A  2014-01-02 02:00:00     A  1
    1  B  2014-01-02 03:00:00  B  B  2
    2     2014-01-02 04:00:00  C  C   
    3  C                       C     4
    

    edit 2021-07-26完整回复@dWitty 的评论

    如果你真的想保留 Nat 和 NaN 值而不是文本,你只需要为你的文本列填写 Na 在你的例子中,这是 A、C、D

    您只需为您的列发送替换 value 的字典。每列的值可以不同。对于您的情况,您只需要构建字典

    # default values to replace NA (None)
    # values = {"A": "", "C": "", "D": ""}
    values = (dict([[e,""] for e in ['A','C','D']]))
    df.fillna(value=values, inplace=True)
    
    df
    Out[142]: 
       A                   B  C  D    E
    0  A 2014-01-02 02:00:00     A  1.0
    1  B 2014-01-02 03:00:00  B  B  2.0
    2    2014-01-02 04:00:00  C  C  NaN
    3  C                 NaT  C     4.0
    

    【讨论】:

    • 这应该是答案
    • 该问题明确询问有关替换 None only,而不是任何 NaN
    【解决方案2】:

    看起来None 正在升级为NaN,因此您不能像往常一样使用replace,以下工作:

    In [126]:
    mask = df.applymap(lambda x: x is None)
    cols = df.columns[(mask).any()]
    for col in df[cols]:
        df.loc[mask[col], col] = ''
    df
    
    Out[126]:
       A                   B  C  D   E
    0  A 2014-01-02 02:00:00     A   1
    1  B 2014-01-02 03:00:00  B  B   2
    2    2014-01-02 04:00:00  C  C NaN
    3  C                 NaT  C      4
    

    因此,我们使用applymap 生成None 值的掩码,然后使用此掩码遍历感兴趣的每一列,并使用布尔掩码设置值。

    【讨论】:

      【解决方案3】:

      由于您希望更改的相关列都是对象,因此您只需使用 dtype 属性指定它(为了完整性,我在字符串和 unicode 中添加)并使用fillna

      所以:

      for c in df:
         if str(df[c].dtype) in ('object', 'string_', 'unicode_'):
              df[c].fillna(value='', inplace=True)
      

      这将使数字和日期列不受影响。

      查看所有列的数据类型:

      df.dtypes 
      

      【讨论】:

        【解决方案4】:

        对于那些试图替换None,而不仅仅是np.nan(在here 中有介绍)的人

        default_value = ""
        df.apply(lambda x: x if x is not None else default_value)
        

        这是一个不错的单行

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-03
          • 2022-01-03
          • 2015-01-06
          • 2016-01-22
          • 1970-01-01
          • 2017-04-04
          • 2021-07-12
          • 1970-01-01
          相关资源
          最近更新 更多