如何在dtype = str的数据帧上使用dropna?

时间:2017-08-22 12:09:47

标签: python pandas dataframe nan missing-data

当我有这样的数据框时:

import pandas as pd
import numpy as np    

df = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype=float)
df.set_value('a', 'D', 4.0)
df.set_value('b', 'E', 10.0)

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN
c  NaN   NaN NaN

通过调用:

,我可以轻松删除仅包含NaNs的行
df = df.dropna(how='all')

产生

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN

如何在使用dtype=str初始化的数据框上执行相同的操作?以下不起作用:

df2 = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype='str')
df2.set_value('a', 'D', 'foo')
df2.set_value('b', 'E', 'bar')

     D    E  F
a  foo    n  n
b    n  bar  n
c    n    n  n

然后是命令

df2 = df2.dropna(how='all')

返回未修改的数据帧。

4 个答案:

答案 0 :(得分:3)

先呼叫df.replace,然后再呼叫df.dropna

In [1576]: df2.replace('n', np.nan).dropna(how='all')
Out[1576]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN

这似乎是最直接的选择。从我看到的情况来看,一旦您使用NaN初始化数据框,就丢失了dtype=str,因此这更像是一个最佳猜测替代品(您可能拥有合法的非NaN条目n被标记为误报并被删除。

这是John Galt的类似解决方案,但保留NaN s:

In [1584]: df2[~df2.eq('n')].dropna(how='all')
Out[1584]: 
     D    E    F
a  foo  NaN  NaN
b  NaN  bar  NaN

扩展Andrew的评论,您无需转换为dtype=str来设置值。您可以改为使用基于.loc的索引:

In [1586]: df2 = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'))
      ...: df2.loc['a', 'D'] = 'foo'
      ...: df2.loc['b', 'E'] = 'bar'
      ...: 

In [1587]: df2
Out[1587]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN
c  NaN  NaN NaN

现在,

In [1588]: df2.dropna(how='all')
Out[1588]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN

答案 1 :(得分:2)

他们不再是NaN。您可以像

一样过滤它们
In [503]: df2[~df2.eq('n').all(1)]
Out[503]:
     D    E  F
a  foo    n  n
b    n  bar  n

答案 2 :(得分:1)

由于您已将np.nan转换为n <class 'str'>,因此您也可以执行以下操作:

df2[~(df2 == 'n').all(axis=1)]
     D    E  F
a  foo    n  n
b    n  bar  n

如果您的实际数据包含“n”,显然这是不安全的。

答案 3 :(得分:1)

您可以使用真实numpy.nan值替换字符串:

df2.replace('n',np.nan).dropna(how = 'all')

哪个会有用,但也会更改您可能要保留的数据框中的'n'值。在这种情况下,删除仅包含值'n'的行:

df2[(df2.T != 'n').any()]

此外,第二种解决方案在计算上更有效:

%timeit df2.replace('n',np.nan).dropna(how = 'all')
985 µs ± 8.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df2[(df2.T != 'n').any()]
449 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)