Python:如何使用不同的分隔符读取csv文件?

时间:2016-09-14 08:30:34

标签: python csv pandas

这是我的txt.file的第一行

0.112296E+02-.121994E-010.158164E-030.158164E-030.000000E+000.340000E+030.328301E-010.000000E+00

应该有8列,有时用' - '分隔,有时用'。'。它非常令人困惑,我只需要处理文件,我没有生成它。

第二个问题:我如何使用不同的列?没有标题,所以可能:

df.iloc[:,0] ..?

3 个答案:

答案 0 :(得分:4)

正如评论中所述,这可能是科学记数法中的数字列表,除了简单地粘在一起之外,它们之间没有任何区别。 它可以解释为:

0.112296E+02
-.121994E-010
.158164E-030
.158164E-030
.000000E+000
.340000E+030
.328301E-010
.000000E+00

0.112296E+02
-.121994E-01
0.158164E-03
0.158164E-03
0.000000E+00
0.340000E+03
0.328301E-01
0.000000E+00

假设第二种解释更好,诀窍是每12个字符均匀分割。

data = [line[i:i+12] for i in range(0, len(line), 12)]

如果真的第一个解释更好,那么我就使用REGEX

import re
line = '0.112296E+02-.121994E-010.158164E-030.158164E-030.000000E+000.340000E+030.328301E-010.000000E+00'
pattern = '[+-]?\d??\.\d+E[+-]\d+'
data = re.findall(pattern, line)

修改

显然,您需要遍历文件中的每一行,并将其添加到您的数据框中。这在熊猫中是一件相当低效的事情。因此,如果您的首选解释是固定宽度,我会选择@Ev。 Kounis'回答:df = pd.read_fwf(myfile, widths=[12]*8)

否则,效率低下的方法是:

df = pd.DataFrame(columns=range(8))
with open(myfile, 'r') as f_in:
    for i, lines in enumerate(f_in):
        data = re.findall(pattern, line)
        df.loc[i] = [float(d) for d in data]

这里要注意的两件事是必须使用列名称初始化DataFrame(此处为[0,1,2,3..7],但您可能知道更好的标识符);并且正则表达式给了我们必须被渲染到浮点数的字符串。

答案 1 :(得分:3)

正如我在评论中所说,它不是多个分隔符的情况,它只是一个固定的宽度格式。 Pandas有一种方法来读取此类文件。试试这个:

df = pd.read_fwf(myfile, widths=[12]*8)
print(df)  # prints -> [0.112296E+02, -.121994E-01, 0.158164E-03, 0.158164E-03.1, 0.000000E+00, 0.340000E+03, 0.328301E-01, 0.000000E+00.1]

对于宽度,您必须提供看起来像 12 的单元格宽度,以及您说的列数 8

您可能会注意到读取的结果并不完美(请注意第4个和最后一个元素中逗号之前的.1),但我正在处理它。

或者,你可以这样做“手动”

myfile = r'C:\Users\user\Desktop\PythonScripts\a_file.csv'
width = 12
my_content = []
with open(myfile, 'r') as f_in:
    for lines in f_in:
        data = [float(lines[i * width:(i + 1) * width]) for i in range(len(lines) // width)]
        my_content.append(data)
print(my_content)  # prints -> [[11.2296, -0.0121994, 0.000158164, 0.000158164, 0.0, 340.0, 0.0328301, 0.0]]

并且每一行都是嵌套列表。

答案 2 :(得分:1)

可能的解决方案如下:

row = '0.112296E+02-.121994E-010.158164E-030.158164E-030.000000E+000.340000E+030.328301E-010.000000E+00'
chunckLen = 12
for i in range(0, len(row), chunckLen):
    print(row[0+i:chunckLen+i])

您可以轻松扩展代码以处理更常见的情况。