以下代码生成 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 |
+---+---+---------------------+---+------+---+
NaT
和NaN
也会被替换,我不想要。如何正确有效地实现这一目标?
答案 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)
这是一个很好的单线纸