使用两个不同的分隔符读取CSV

时间:2015-08-05 15:28:32

标签: python pandas

我有example file我正在使用的文件类型。 有时分隔符为|,有时则为*

我最接近成功阅读的是:

data = pd.read_csv('filename', 
                   skiprows=244, sep=r'\|',
                   header=None,
                   names=['A','B','C','D','E'])
new = data['E']
df = new.str.split().apply(lambda x: pd.Series(x))
df = df.convert_objects(convert_numeric=True)

但问题是,我最终得到None行,其中我的分隔符是*

有没有办法根据两个不同的分隔符分隔这个文件?我考虑过使用正则表达式匹配|*

data = pd.read_csv('filename', 
                   skiprows=244, nrows=5, sep=r'(\| | \*)',
                   header=None,
                   names=['A','B','C','D'])

似乎也不起作用。虽然我不是最好的reg表达式。

编辑: 我也尝试过使用sep=r'\s*',但看看*在文件中如何移动,它会使某些行移位,因此列不对齐。

3 个答案:

答案 0 :(得分:1)

这些星号到处都是有问题的,因为正如你所提到的,有时它们会取代|分隔符,有时候它们会在一个看似随机的字段中间。

幸运的是,你的文件似乎是固定宽度,pandas knows how to handleread_fwf(固定宽度文件)。

让我们来看看这个令人讨厌的数据文件的一小部分,它显示了两个星号位置:

 |                   *                   |                   |  0.1108      0.0085 ( 1.883%)     0.1066 ( 0.504%)
 |                   |                   |                   |  0.1112      0.0001 (20.851%)     0.1066 ( 0.504%)
 |                   |                   |                   |  0.1116      0.0005 ( 7.536%)     0.1072 ( 0.502%)
 |                *  |                   |                   |  0.1120      0.0059 ( 2.266%)     0.1130 ( 0.488%)
 |                   |                   |                   |  0.1124      0.0001 (16.439%)     0.1131 ( 0.487%)

我们可以通过对字符位置进行一些仔细(但无聊)的计算来阅读:

In [9]: colspecs = [(64, 71), (76, 83), (85, 90), (97, 104), (106, 111)]

In [11]: pd.read_fwf('my_file.csv', colspecs=colspecs, header=None)
Out[11]: 
        0       1      2       3      4
0  0.1108  0.0085  1.883  0.1066  0.504
1  0.1112  0.0001  0.851  0.1066  0.504
2  0.1116  0.0005  7.536  0.1072  0.502
3  0.1120  0.0059  2.266  0.1130  0.488
4  0.1124  0.0001  6.439  0.1131  0.487

答案 1 :(得分:0)

你可以采用老式的方式,建立一个清单:

rows = []
for line in open('filename'):
    var1 = int(line[62:70])
    ....
    rows.append([var1, ...])

data = pd.DataFrame(data=rows, columns=['A','B','C','D'])

答案 2 :(得分:0)

with open('C:/example_file.txt') as f:
    content = [x.strip('\n') for x in f.readlines()]
content.pop(0)
cleancontent = []
for index, item in enumerate(content):
    cleancontent.append(content[index][62:])
cleancontent

然后将其转换为数据框。