【问题标题】:Importing a CSV with random number of columns导入具有随机列数的 CSV
【发布时间】:2015-07-02 15:28:21
【问题描述】:

我有一个脚本,它以 CSV 格式读取一些测量数据,然后用它进行各种绘图和填充。

现在我有了一个新数据集,有些白痴认为在行尾添加一些随机 cmets 很有帮助,如下所示:

01.02.1988 00:00:00   ;   204.94     
01.03.1988 00:00:00   ;   204.87 ; something
01.04.1988 00:00:00   ;   205.41     
01.05.1988 00:00:00   ;   205.64 ; something ; something else    
01.06.1988 00:00:00   ;   205.59 ; also something    
01.07.1988 00:00:00   ;   205.24

这让我很开心

ValueError: Expected 2 fields in line 36, saw 3

等等。

根据thisthis,我在阅读时必须使用names=['whatever','else']参数。

但不知何故,这有各种各样的错误。所以这里有一些例子:

CSV 文件

Stuff
more stuff I dont need
Date;level;crap1;crap2;crap3;crap4;crap5;crap6
01.01.1988 00:00:00   ;   204.87     
01.02.1988 00:00:00   ;   204.94     
01.03.1988 00:00:00   ;   204.87 

“漂亮”的标题显然是“手工制作的”,但我应该可以跳过它!?

CSV 阅读器

ValReader = pd.read_csv(csv_list[counter],sep=r'\s*;',skiprows=DateStart,names=['Date','level','crap1','crap2','crap3','crap4','crap5','crap6'],usecols=['Date','level'],index_col='Date',dayfirst=True,parse_dates=True)

我得到了什么

print 'ValReader'
                         level
Date                          
Date                     level
01.04.2003 00:00:00     200.76
01.05.2003 00:00:00     200.64
01.06.2003 00:00:00     200.53

随后,将级别作为字符串处理。

好吧,很简单,CSV 中的手动标题行(在以前的版本中运行良好,只需要处理好的数据)是罪魁祸首,所以我只是将 skiprows 设置为 skiprows=DateStart+1,但结果在

ValueError: Number of passed names did not match number of header fields in the file

显然,我完全迷失了 pandas 如何处理列的名称和位置。

【问题讨论】:

    标签: python csv pandas


    【解决方案1】:

    我以前也有这个问题,但是这里有一个解决方案。

    解决它的一种方法是使用正则表达式来解析分隔符,因为这会退回到 python 引擎,而在 C 引擎中,您可以跳过坏行警告,并可以指定您想要的

    例如:

    In [1]: import io
    
    In [2]: import pandas as pd
    
    In [3]: s = io.StringIO(u'''Stuff
    more stuff I dont need
    Date;level;crap1;crap2;crap3;crap4;crap5;crap6
    01.01.1988 00:00:00   ;   204.87
    01.02.1988 00:00:00   ;   204.94
    01.03.1988 00:00:00   ;   204.87 ''')
    # I use skiprows=2 instead of DateStart here
    # after settings error_bad_lines=False, you can parse the csv OK...
    In [4]: ValReader = pd.read_csv(s, sep=';', skiprows=2, usecols=['Date', 'level'], 
                                    index_col='Date', dayfirst=True, parse_dates=True, 
                                    error_bad_lines=False)
    
    In [5]: ValReader
    Out[5]:
                 level
    Date
    1988-01-01  204.87
    1988-02-01  204.94
    1988-03-01  204.87
    
    In [6]: ValReader['level'].dtype
    Out[6]: dtype('float64')
    

    希望这对您遇到的问题有所帮助。

    【讨论】:

    • 我忘记了我究竟为什么使用正则表达式,但我记得在; 之前和之后作为填充的各种空格存在一些问题。但它似乎工作。但是现在它似乎忽略了我添加的na_values='hole',因此ValueError: could not convert string to float: hole 出错了。我会多玩一会儿,看看是什么原因造成的。
    • @JC_CL,据我了解,通常有一些方法可以消除 csv 文件中正则表达式的使用。对于您的用例,只要必填字段不包含嘈杂的;,您就可以按原样解析数据并随后清除噪声。但无论如何希望你能弄清楚并祝你好运:)
    • 我不确定我的数据中真正发生了什么变化,或者我的脚本中还有什么变化,但目前,无正则表达式 sep 似乎有效。我无法弄清楚我的na_values到底发生了什么,所以我以残酷的方式做了,并在我的预处理中使用sed将hole更改为NaN。不优雅,但它似乎工作。下一个WTF时刻然后……
    • @JC_CL,很高兴你暴力破解了它。作为旁注,您还可以设置warn_bad_lines=True sed 源,虽然不优雅,但绝对是一种方法。问题不在于您,而在于来源 provider 恐怕;)
    猜你喜欢
    • 1970-01-01
    • 2014-05-21
    • 2019-06-16
    • 1970-01-01
    • 2015-07-23
    • 2021-08-03
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    相关资源
    最近更新 更多