我正在读取 CSV 数据以用作 pandas 数据框,但 CSV 似乎不遵循任何理智的约定(除了用作;分隔符,每个人都应该......)。看来唯一的目标是让它们在文本编辑器中打开时看起来不错以下是一些示例(设置为变量,以便它们可用于读者示例):ex1="""Type: Some MetadataUser: More MetadataData:01.10.1939 00:00:00 ; 1,1 ; 01.12.1939 00:00:00 ; 1 ; 01.01.1940 00:00:00 ; 10 ; """好的,小数逗号(简单),分号分隔符(简单),dayfirst(简单)和一堆元数据(skiprows,也简单)。ts = pd.read_csv(io.StringIO(ex1), skiprows=4, decimal=',', sep=';', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'])print(ts结果是一个很好的数据框 valdate1939-10-01 1.11939-12-01 1.01940-01-01 10.0andts.index是一个很好的DatetimeIndexandtype(ts.val[0])是一个numpy.float64,因为它应该是这样。但让我们介绍一种创造性的标记方式NaN:ex2="""Type: Some MetadataUser: More MetadataData:01.10.1939 00:00:00 ; 1,1; 01.12.1939 00:00:00 ; NÄ ; 01.01.1940 00:00:00 ; 10 ; """上面的代码ts=read_csv...仍然可以正常工作,但不会出现错误,但NÄ会破坏val列并将其转换为字符串。但是当我将其更改为ts = pd.read_csv(io.StringIO(ex2), skiprows=4, decimal=',', sep=';', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'], na_values='NÄ')使用na_values,整个事情都会失败。print(ts) valdate1939-10-01 1,11939-12-01 NÄ1940-01-01 10它不仅不接受NÄas NaN,还将所有vals 转换为字符串,从而忽略小数逗号并保留尾随空格。ts.val[0]是现在' 1,1',所以简单ts.val = ts.val.astype(float)的当然失败了。我做错了什么na_values='NÄ'?为什么它也会打破decimal','并添加空格?看起来skipinitialspace=True应该有帮助,但当然NÄ仍然打破了val专栏。 sep='\s*[;]s*'看起来很有希望,并且ts = pd.read_csv(io.StringIO(ex2), skiprows=4, decimal=',' ,sep='\s*[;]s*', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'], na_values='NÄ')(注意小数点!),但现在我遇到了奇怪的情况,它确实替换了逗号,但ts.val[0]现在又是一个字符串,并且仍然有尾随空格(' 1.1')。那么我如何读取这些无聊的文件呢?我当前使用的解决方法是使用纯Python读取CSV(无论如何我都必须读取标题(实际文件中的40行))并将其写入正确的CSV,以便用pandas读取:但是对于几千个 CSV 文件,大小达到一兆字节,这并不是一个真正的最佳解决方案,所以我想NÄ在导入中解决这个问题。
1 回答
狐的传说
TA贡献1804条经验 获得超3个赞
您的sep指定错误(它s*以 而不是 结尾\s*,这意味着它正在寻找 0 到无限个s字符之间)。这就是为什么您只捕获前导空格而不捕获 后的尾随空格;。顺便说一句,这也干扰了 (1),因为您试图替换'NÄ'但值为' NÄ'。sep='\s*\;\s*'代替使用。
您将来可以做的一件事是自己打印出有问题的值,以确保它们包含他们认为您包含的内容,例如ts.iloc[1].val。
另外,如果NaNunicode 中的值有问题,您可以在解析之前将其剥离:
csv = io.StringIO(ex2.replace(u'N\xc4', '[MISSING]'))
ts = pd.read_csv(csv,
skiprows=4, decimal=',', index_col=0, usecols=[0,1],
dayfirst=True, parse_dates=True, names=['date', 'val'],
na_values='[MISSING]', sep='\s*\;\s*')
...这会给...
val
date
1939-10-01 1.1
1939-12-01 NaN
1940-01-01 10.0
添加回答
举报
0/150
提交
取消