Pandas read_csv使用字符串'nan'填充空值,而不是解析日期

时间:2013-04-22 22:39:07

标签: python date csv pandas missing-data

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

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分配给缺失值并仍然解析有效日期?

3 个答案:

答案 0 :(得分:7)

这是解析器中目前的一个小问题,请参阅:https://github.com/pydata/pandas/issues/3062 简单的解决方法是在读取后强制转换列(并使用NaT填充nans,这是非时间标记,相当于日期时间为nan)。这应该适用于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]

如果您的数据中出现字符串'nan',则可以执行以下操作:

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]

答案 1 :(得分:3)

您可以在na_values=["nan"]函数调用中传递read_csv参数。这将读取字符串nan值并将其转换为正确的np.nan格式。

有关详细信息,请参阅here

答案 2 :(得分: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)

然后你应该好好去!