用熊猫中的NaN替换空白值(空格)

时间:2012-11-18 22:22:39

标签: python pandas dataframe

我想在Pandas数据框中找到包含空格(任意数量)的所有值,并用NaN替换这些值。

任何想法如何改进?

基本上我想转此:

                   A    B    C
2000-01-01 -0.532681  foo    0
2000-01-02  1.490752  bar    1
2000-01-03 -1.387326  foo    2
2000-01-04  0.814772  baz     
2000-01-05 -0.222552         4
2000-01-06 -1.176781  qux     

进入这个:

                   A     B     C
2000-01-01 -0.532681   foo     0
2000-01-02  1.490752   bar     1
2000-01-03 -1.387326   foo     2
2000-01-04  0.814772   baz   NaN
2000-01-05 -0.222552   NaN     4
2000-01-06 -1.176781   qux   NaN

我已经设法用下面的代码来做,但是男人是丑陋的。它不是Pythonic,我敢肯定它也不是最有效的熊猫用途。我循环遍历每一列,并对通过应用对每个值进行正则表达式搜索的函数生成的列掩码进行布尔替换,并在空格上进行匹配。

for i in df.columns:
    df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None

只需迭代可能包含空字符串的字段即可对其进行优化:

if df[i].dtype == np.dtype('object')

但这并没有太大改善

最后,这段代码将目标字符串设置为None,这与Pandas的函数如fillna()一起使用,但如果我能直接插入NaN而不是{ {1}}。

14 个答案:

答案 0 :(得分:132)

我认为df.replace()完成了这项工作:

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

# replace field that's entirely space (or empty) with NaN
print(df.replace(r'^\s*$', np.nan, regex=True))

产地:

                   A    B   C
2000-01-01 -0.532681  foo   0
2000-01-02  1.490752  bar   1
2000-01-03 -1.387326  foo   2
2000-01-04  0.814772  baz NaN
2000-01-05 -0.222552  NaN   4
2000-01-06 -1.176781  qux NaN

正如Temak指出的那样,如果您的有效数据包含空格,请使用df.replace(r'^\s+$', np.nan, regex=True)

答案 1 :(得分:32)

怎么样:

d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

applymap函数将函数应用于数据帧的每个单元格。

答案 2 :(得分:31)

如果您想要替换空字符串并且仅包含空格的记录,正确答案!:

df = df.replace(r'^\s*$', np.nan, regex=True)

接受的答案

df.replace(r'\s+', np.nan, regex=True)

不替换空字符串!,您可以尝试使用稍微更新的给定示例:

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'fo o', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', ''],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

请注意,' fo o'虽然它包含一个空格,但不会被Nan取代。 进一步说明,这很简单:

df.replace(r'', np.NaN)

也不起作用 - 尝试一下。

答案 3 :(得分:13)

我会这样做:

df = df.apply(lambda x: x.str.strip()).replace('', np.nan)

df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan)

您可以删除所有str,然后用np.nan替换空str。

答案 4 :(得分:4)

最简单的解决方案:

df = df.replace(r'^\s+$', np.nan, regex=True)

答案 5 :(得分:3)

如果要从CSV文件导出数据,可以这么简单:

df = pd.read_csv(file_csv, na_values=' ')

这将创建数据框,并将空白值替换为Na

答案 6 :(得分:1)

这对我有用。 导入csv文件时,我添加了na_values =''。默认的NaN值中不包含空格。

df= pd.read_csv(filepath,na_values = ' ')

答案 7 :(得分:0)

对于一个非常快速和简单的解决方案,您可以使用mask方法检查单个值的相等性。

df.mask(df == ' ')

答案 8 :(得分:0)

你也可以使用过滤器来完成它。

df = PD.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '])
    df[df=='']='nan'
    df=df.astype(float)

答案 9 :(得分:0)

print(df.isnull().sum()) # check numbers of null value in each column

modifiedDf=df.fillna("NaN") # Replace empty/null values with "NaN"

# modifiedDf = fd.dropna() # Remove rows with empty values

print(modifiedDf.isnull().sum()) # check numbers of null value in each column

答案 10 :(得分:0)

这不是一个很好的解决方案,但是似乎有效的方法是保存到XLSX,然后将其重新导入。不确定原因,此页面上的其他解决方案对我不起作用。

data.to_excel(filepath, index=False)
data = pd.read_excel(filepath)

答案 11 :(得分:0)

这些都接近正确的答案,但是我不会说任何解决问题的方法,同时让其他阅读您的代码的人仍然最容易理解。我想说的答案是BrenBarn's Answeranswer下面的tuomasttik评论的结合。 BrenBarn的答案利用内置的isspace,但不支持按照OP的要求删除空字符串,我倾向于将其归因于用null替换字符串的标准用例。

我用.apply重写了它,因此可以在pd.Seriespd.DataFrame上调用它。


Python 3:

要替换空字符串或整个空格的字符串:

df = df.apply(lambda x: np.nan if isinstance(x, str) and (x.isspace() or not x) else x)

要替换整个空格的字符串:

df = df.apply(lambda x: np.nan if isinstance(x, str) and x.isspace() else x)

要在Python 2中使用此功能,您需要将str替换为basestring

Python 2:

要替换空字符串或整个空格的字符串:

df = df.apply(lambda x: np.nan if isinstance(x, basestring) and (x.isspace() or not x) else x)

要替换整个空格的字符串:

df = df.apply(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

答案 12 :(得分:0)

这应该有效

df.loc[df.Variable == '', 'Variable'] = 'Value'

df.loc[df.Variable1 == '', 'Variable2'] = 'Value'

答案 13 :(得分:-1)

我尝试了这段代码,它对我有用: df.applymap(lambda x:如果x ==“” else x,则为“ NaN”