2013-04-22 152 views
4

我将np.nan分配给DataFrame的列中的缺失值。然后使用to_csv将DataFrame写入到csv文件中。如果我使用文本编辑器打开文件,则生成的csv文件在缺失值的逗号之间没有任何内容。但是当我使用read_csv将该csv文件读回到DataFrame中时,缺少的值将成为字符串'nan'而不是NaN。因此,isnull()不起作用。例如:Pandas read_csv用字符串'nan'填充空值,而不是解析日期

In [13]: df 
Out[13]: 
    index value date 
0 975 25.35 nan 
1 976 26.28 nan 
2 977 26.24 nan 
3 978 25.76 nan 
4 979 26.08 nan 

In [14]: df.date.isnull() 
Out[14]: 
0 False 
1 False 
2 False 
3 False 
4 False 

我做错了什么?我应该将一些其他值而不是np.nan指定为缺失值,以便isnull()能够提取?

编辑:对不起,忘了提及我也设置parse_dates = [2]来解析该列。该列包含缺少一些行的日期。我想缺少的行是NaN。 EIDT:我只是发现问题实际上是由于parse_dates造成的。如果日期列包含缺失值,则read_csv将不会分析该列。相反,它会将日期读取为字符串,并将字符串'nan'分配给空值。

In [21]: data = pd.read_csv('test.csv', parse_dates = [1]) 

In [22]: data 
Out[22]: 
    value  date id 
0  2 2013-3-1 a 
1  3 2013-3-1 b 
2  4 2013-3-1 c 
3  5  nan d 
4  6 2013-3-1 d 

In [23]: data.date[3] 
Out[23]: 'nan' 

pd.to_datetime无法正常工作或:

In [12]: data 
Out[12]: 
    value  date id 
0  2 2013-3-1 a 
1  3 2013-3-1 b 
2  4 2013-3-1 c 
3  5  nan d 
4  6 2013-3-1 d 

In [13]: data.dtypes 
Out[13]: 
value  int64 
date  object 
id  object 

In [14]: pd.to_datetime(data['date']) 
Out[14]: 
0 2013-3-1 
1 2013-3-1 
2 2013-3-1 
3   nan 
4 2013-3-1 
Name: date 

有没有办法有read_csv parse_dates与包含遗漏值列工作?即将NaN分配给缺失值并仍然解析有效日期?

+0

你能否包含csv的头部(所以我们可以重新创建)? – 2013-04-22 23:18:25

回答

3

您可以通过read_csv函数调用中的na_values=["nan"]参数。这将读取字符串nan值并将其转换为适当的np.nan格式。

有关更多信息,请参阅here

+0

对不起,也许我没有解释清楚。我不想将字符串'nan'归类为NaN。我说的是,read_csv将csv文件中的空值读入字符串'nan',假定为NaN。如果我用文本编辑器打开csv文件,两个逗号之间没有任何内容。 – ezbentley 2013-04-22 22:58:35

+1

尝试'na_values = ['nan','']'这应该读取字符串nan和空字符串值作为np.nan。 – bdiamante 2013-04-22 23:50:57

+2

这仍然不起作用。我认为na_values选项不适用于被解析为日期的列。问题是真的parse_dates不适用于缺少值的列。 – ezbentley 2013-04-22 23:54:59

7

这是当前解析器中的一个bug,请参阅:https://github.com/pydata/pandas/issues/3062 简单的解决方法是在读取它后强制转换列(并且将用NaT填充,这是非A-Time标记,相当于到日期时间为止)。这应该在0.10.1

In [22]: df 
Out[22]: 
    value  date id 
0  2 2013-3-1 a 
1  3 2013-3-1 b 
2  4 2013-3-1 c 
3  5  NaN d 
4  6 2013-3-1 d 

In [23]: df.dtypes 
Out[23]: 
value  int64 
date  object 
id  object 
dtype: object 

In [24]: pd.to_datetime(df['date']) 
Out[24]: 
0 2013-03-01 00:00:00 
1 2013-03-01 00:00:00 
2 2013-03-01 00:00:00 
3     NaT 
4 2013-03-01 00:00:00 
Name: date, dtype: datetime64[ns] 

工作,如果字符串“南”实际上可以出现在你的数据,你可以这样做:

In [31]: s = Series(['2013-1-1','2013-1-1','nan','2013-1-1']) 

In [32]: s 
Out[32]: 
0 2013-1-1 
1 2013-1-1 
2   nan 
3 2013-1-1 
dtype: object 

In [39]: s[s=='nan'] = np.nan 

In [40]: s 
Out[40]: 
0 2013-1-1 
1 2013-1-1 
2   NaN 
3 2013-1-1 
dtype: object 

In [41]: pandas.to_datetime(s) 
Out[41]: 
0 2013-01-01 00:00:00 
1 2013-01-01 00:00:00 
2     NaT 
3 2013-01-01 00:00:00 
dtype: datetime64[ns] 
+0

to_datetime是否使用字符串'nan'?它仍然不适合我。它看起来像你的df.date已经包含一个有效的NaN,而read_csv给了我一个字符串'南'。请参阅我的编辑。谢谢。 – ezbentley 2013-04-23 00:19:41

+0

尝试更新的解决方案(这是一些手动),但与''na_values = ['南']''传递给read_csv你可以实现这个很容易 – Jeff 2013-04-23 00:24:15

+0

我认为这样做手动。但最根本的问题是,如果您要求read_csv将列解析为日期,并且该列包含缺失值,那么read_csv将不会分析日期并将字符串'nan'替换为缺少的值。因此,na_values = ['nan']将不会做任何事情,因为您的更新意味着'nan'不存在于原始csv文件中。 – ezbentley 2013-04-23 04:36:30

0

我得到了同样的问题。使用导入csv文件

dataframe1 = pd.read_csv(input_file, parse_date=['date1', 'date2']) 

其中date1包含有效日期,而date2是空列。显然,dataframe1 ['date2']填充了整列'nan'。

这种情况是,在指定dataframe中的日期列并使用read_csv导入数据后,空日期列将填充字符串'nan'而不是NaN。

后者可以被numpy和pandas识别为NULL,而第一个不能。

一个简单的解决方案是:

from numpy import nan 
dataframe.replace('nan', nan, inplace=True) 

然后你应该是好去!