python以特定格式读取文件

时间:2017-01-31 19:01:06

标签: python numpy text

我的文件格式如下:

36.1 37.1 A: Hi, how are you?
39.1 40.1 B: I am ok!

我正在使用numpy.loadtxt()使用dtype = np.dtype([('start', '|S1'), ('end', 'f8'),('person','|S1'),('content','|S100')])

来阅读此文件

前3列很好,但字符串部分总是有问题:格式不匹配。我想这是因为每个发言者都说可变长度的单词。有谁知道更好的方法来解决这个问题?

非常感谢,

2 个答案:

答案 0 :(得分:0)

我建议手动阅读文本而不是numpy,只是迭代文件中的行。

with open("read.txt", "r") as infile:
    chats = []
    for i in infile:
        data = i.split(":")
        start, end, name, content = data[0].split(" ")[0], data[0].split(" ")[1], data[0].split(" ")[2], data[1].strip("\n")
        chats.append([start, end, name, content])

文件打开并逐行阅读,而开头,结尾,名称和内容作为子列表附加到列表聊天中。

答案 1 :(得分:0)

在您的文件中,大多数列由空格分隔,但最后一个字段中的字符串也是如此。相反,如果你有;或分隔字段的选项卡,会更容易。

但是genfromtxt让我们指定字段宽度而不是分隔符。因此,我可以使用您的文本示例

In [912]: dt=np.dtype([('start', 'f8'), ('end', 'f8'),('person','|S3'),('content','|S100')])
In [913]: np.genfromtxt(txt.splitlines(),dtype=dt,delimiter=[4,6,3,20])
Out[913]: 
array([( 36.1,  37.1, b'A: ', b'Hi, how are you?'),
       ( 39.1,  40.1, b'B: ', b'I am ok!')], 
      dtype=[('start', '<f8'), ('end', '<f8'), ('person', 'S3'), ('content', 'S100')])

split有一个maxsplit参数,如果您自己阅读该文件,该参数可能很方便。

In [922]: alist = [tuple(line.split(maxsplit=3)) for line in txt.splitlines()]
In [923]: alist
Out[923]: 
[(b'36.1', b'37.1', b'A:', b'Hi, how are you?'),
 (b'39.1', b'40.1', b'B:', b'I am ok!')]

请注意,这是一个元组列表,可以使用您的dtype轻松转换为结构化数组:

In [924]: np.array(alist, dtype=dt)
Out[924]: 
array([( 36.1,  37.1, b'A:', b'Hi, how are you?'),
       ( 39.1,  40.1, b'B:', b'I am ok!')], 
      dtype=[('start', '<f8'), ('end', '<f8'), ('person', 'S3'), ('content', 'S100')])

我用过的测试

In [900]: txt=b"""36.1 37.1 A: Hi, how are you?
     ...: 39.1 40.1 B: I am ok!
     ...: """

但您可以逐行读取文件或同时读取所有文件并执行相同的操作。 genfromtxt与文件或行列表一样适用。

另一种选择是逐行读取文件,用所需的分隔符替换选定的空格并将其传递给genfromtxt

例如,制作;分隔文字(字符串中已有,):

In [935]: alist = [b';'.join(line.split(maxsplit=3)) for line in txt.splitlines()]
In [936]: alist
Out[936]: [b'36.1;37.1;A:;Hi, how are you?', b'39.1;40.1;B:;I am ok!']
In [937]: np.genfromtxt(alist, delimiter=';', dtype=dt)
Out[937]: 
array([( 36.1,  37.1, b'A:', b'Hi, how are you?'),
       ( 39.1,  40.1, b'B:', b'I am ok!')], 
      dtype=[('start', '<f8'), ('end', '<f8'), ('person', 'S3'), ('content', 'S100')])