Pandas read_csv 用字符串“nan”填充空值,而不是解析日期
Posted
技术标签:
【中文标题】Pandas read_csv 用字符串“nan”填充空值,而不是解析日期【英文标题】:Pandas read_csv fills empty values with string 'nan', instead of parsing date 【发布时间】:2013-04-15 23:51:37 【问题描述】:我将 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 处理包含缺失值的列? IE。将 NaN 分配给缺失值并仍然解析有效日期?
【问题讨论】:
能否包含 csv 的头部(以便我们重新创建)? 【参考方案1】:您可以在read_csv
函数调用中传递na_values=["nan"]
参数。这将读取字符串 nan 值并将它们转换为正确的np.nan
格式。
请参阅here 了解更多信息。
【讨论】:
对不起,我可能没有解释清楚。我不想将字符串“nan”归类为 NaN。我要说的是,read_csv 将 csv 文件中的空值读入字符串 'nan' 中,就像 NaN 一样。如果我用文本编辑器打开 csv 文件,两个逗号之间没有任何内容。 试试na_values=['nan', '']
这应该读取字符串 nan 和空白字符串值作为 np.nan。
这仍然不起作用。我认为 na_values 选项不适用于被解析为日期的列。问题在于 parse_dates 确实不适用于缺少值的列。【参考方案2】:
目前这是解析器中的一个 buglet,请参阅:https://github.com/pydata/pandas/issues/3062 简单的解决方法是在您读入该列后强制转换该列(并将使用 NaT 填充 nans,NaT 是非时间标记,相当于日期时间的 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]
【讨论】:
to_datetime 是否适用于字符串“nan”?它仍然对我不起作用。看起来您的 df.date 已经包含一个有效的 NaN,而 read_csv 给了我一个字符串“nan”。请看我的编辑。谢谢。 尝试使用更新的解决方案(这有点手动),但使用na_values=['nan']
传递给 read_csv 你可以很容易地做到这一点
我考虑手动执行此操作。但根本问题是,如果您要求 read_csv 将列解析为日期并且该列包含缺失值,则 read_csv 不会解析日期并用字符串“nan”代替缺失值。因此, na_values=['nan'] 不会做任何事情,因为原始 csv 文件中不存在“nan”,正如您的更新所暗示的那样。【参考方案3】:
我遇到了同样的问题。使用导入 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)
然后你应该好好去!
【讨论】:
以上是关于Pandas read_csv 用字符串“nan”填充空值,而不是解析日期的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:ValueError:无法将浮点 NaN 转换为整数
将包含 NaN 的 Pandas 列转换为 dtype `int`
如何在使用 pandas.read_csv 读取 csv 文件时将 pandas.dataframe 中的元素转换为 np.float?
如何在使用 pandas.read_csv 读取 csv 文件时将 pandas.dataframe 中的元素转换为 np.float?