如何在pandas的字符串列中按NaN过滤?

时间:2016-05-11 08:47:47

标签: python pandas

我正在使用熊猫0.18。我使用pd.read_csv()从CSV加载了一个数据框,看起来CSV中的空单元格已在数据框中加载为NaN

现在我想找到特定列中具有空值的行数,但我正在努力。

这是我的数据框:

      ods         id provider
0  A86016        NaN     emis
1  L81042     463061      NaN
2  C84013        NaN      tpp
3  G82228     462941     emis
4  C81083        NaN      tpp

这是我从df.describe()获得的:

           ods         id provider
count     9897       7186     9022
unique    8066        192        4
top     N83028     463090     emis
freq         7        169     4860

我想获取CSV中provider为空的所有行。这就是我尝试过的:

>>> print len(df[df.provider == 'NaN'])
0
>>> print len(df[df.provider == np.nan])
0

我可以看到那里有一些NaN值(例如第1行)所以给出了什么?

另外,为什么pandas会将provider等字符串列中的空值转换为NaN - 将它们转换为空字符串会不会更有意义?

2 个答案:

答案 0 :(得分:4)

使用isnull进行比较NaN

df = pd.DataFrame({'ods': {0: 'A86016', 1: 'L81042', 2: 'C84013', 3: 'G82228', 4: 'C81083'}, 
                   'id': {0: np.nan, 1: 463061.0, 2: np.nan, 3: 462941.0, 4: np.nan}, 
                   'provider': {0: 'emis', 1: np.nan, 2: 'tpp', 3: 'emis', 4: 'tpp'}})

print df
         id     ods provider
0       NaN  A86016     emis
1  463061.0  L81042      NaN
2       NaN  C84013      tpp
3  462941.0  G82228     emis
4       NaN  C81083      tpp

print (df[df.provider.isnull()])

      ods        id provider
1  L81042  463061.0      NaN

print len(df[df.provider.isnull()])
1

如果您需要将NaN转换为“使用fillna

df.provider.fillna('', inplace=True)
print df
         id     ods provider
0       NaN  A86016     emis
1  463061.0  L81042         
2       NaN  C84013      tpp
3  462941.0  G82228     emis
4       NaN  C81083      tpp

Docs

  

警告

     

必须要注意的是,在python(和numpy)中,nan的比较并不相同,但是没有。请注意,Pandas / numpy使用np.nan!= np.nan的事实,并像np.nan一样对待None。

In [11]: None == None
Out[11]: True

In [12]: np.nan == np.nan
Out[12]: False
  

因此,与上述相比,标量相等比较与None / np.nan无法提供有用的信息。

In [13]: df2['one'] == np.nan
Out[13]: 
a    False
b    False
c    False
d    False
e    False
f    False
g    False
h    False
Name: one, dtype: bool

但如果nan是字符串:

df = pd.DataFrame({'ods': {0: 'A86016', 1: 'L81042', 2: 'C84013', 3: 'G82228', 4: 'C81083'}, 
                   'id': {0: np.nan, 1: 463061.0, 2: np.nan, 3: 462941.0, 4: np.nan}, 
                   'provider': {0: 'emis', 1: 'nan', 2: 'tpp', 3: 'emis', 4: 'tpp'}})

print df
      ods        id provider
0  A86016       NaN     emis
1  L81042  463061.0      nan
2  C84013       NaN      tpp
3  G82228  462941.0     emis
4  C81083       NaN      tpp


print (df[df.provider == 'nan'])
      ods        id provider
1  L81042  463061.0      nan
  

你知道为什么pandas将空字符串作为NaN而不是空字符串导入吗?

请参阅docs(由我粗体):

  

na_values: str list-like dict ,默认

     

要识别为NA / NaN的其他字符串。如果dict通过,则具体的每列NA值。默认情况下,以下值被解释为NaN:' - 1。#IND','1。#QNAN','1。#IND',' - 1。#QNAN','#N / AN / A',' #N / A','N / A','NA','#N','NULL','NaN',' - 'NN','nan',' - nan',''

答案 1 :(得分:1)

您可以先存储na值,然后删除所有其余值:

without_na = df['provider'].dropna()
df[~df.index.isin(without_na.index)]