如何使用pandas仅用空字符串替换None?

时间:2015-07-08 14:31:16

标签: python pandas

以下代码生成 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也会被替换,我不想要。
  3. 如何正确有效地实现这一目标?

4 个答案:

答案 0 :(得分:7)

足够了

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

答案 1 :(得分:6)

看起来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

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

答案 2 :(得分: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 

答案 3 :(得分:1)

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

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

这是一个很好的单线纸