Python-使用不同的分隔符读取数据文本文件

时间:2018-07-05 15:39:38

标签: python python-3.x numpy

我有一个文件,其中的字段用':'分隔,子字段用';'分隔,子字段中的项目用','分隔。

我想读它Python。一段时间后,我可能可以逐行阅读它,然后拆分所有内容,但我相信这种事情已经存在了吗?

文件的一行:

   0 :   16,  250 :  1 :  0.053 :RIG : DIS :  1 :   48, 220;  2 :   42, 241;  2 :   43, 251;  3 :   25, 266;  1 :   36, 287;  2 

我实际上尝试过:

Dat = np.genfromtxt(path, delimiter= ':', dtype = None, skip_header = 4,  skip_footer = 5, encoding = None)

由于某种原因,我不明白,它只给我文件的第一列。但是,如果我更改为delimiter= ',',它就可以工作。

这给了我7个字段,我实际上可以拆分自己。

然后: 1)您将如何读取该文件? 2)为什么使用np.genfromtxt,我仅使用':'作为分隔符来获得第一列?

2 个答案:

答案 0 :(得分:4)

使用熊猫的解决方案:

data = pd.read_csv('data.txt',
                   sep=";|:|,",
                   header=None,
                   engine='python')

这会将每个值写入新列。希望这会有所帮助。

答案 1 :(得分:0)

In [280]: txt=['   0 :   16,  250 :  1 :  0.053 :RIG : DIS :  1 :   48, 220;  2 
     ...: :   42, 241;  2 :   43, 251;  3 :   25, 266;  1 :   36, 287;  2 '
     ...: ]

In [282]: np.genfromtxt(txt,delimiter=':',dtype=None, encoding=None)
Out[282]: 
array((0, '   16,  250 ', 1, 0.053, 'RIG ', ' DIS ', 1, '   48, 220;  2 ', '   42, 241;  2 ', '   43, 251;  3 ', '   25, 266;  1 ', '   36, 287;  2'),
      dtype=[('f0', '<i8'), ('f1', '<U12'), ('f2', '<i8'), ('f3', '<f8'), ('f4', '<U4'), ('f5', '<U5'), ('f6', '<i8'), ('f7', '<U15'), ('f8', '<U15'), ('f9', '<U15'), ('f10', '<U15'), ('f11', '<U14')])

这是具有11个字段的结构化数组,是整数,字符串和浮点数的混合。这是因为dtype=None告诉它为每一列推导dtype。

,上拆分会产生一个7列数组(此处为1d,因为只有一条输入行,但是会有更多的2d列):

In [283]: np.genfromtxt(txt,delimiter=',',dtype=None, encoding=None)
Out[283]: 
array(['0 :   16', '  250 :  1 :  0.053 :RIG : DIS :  1 :   48',
       ' 220;  2 :   42', ' 241;  2 :   43', ' 251;  3 :   25',
       ' 266;  1 :   36', ' 287;  2'], dtype='<U42')

但是请注意,所有字符串都是。

genfromtxt不需要多个定界符,但是它确实接受了任何输入内容。

因此,如果我定义了一个替换定界符的函数:

In [285]: def foo(astr):
     ...:     return astr.replace(':',',').replace(';',',')
     ...: 
     ...: 
In [286]: np.genfromtxt([foo(a) for a in txt],delimiter=',',dtype=None, encoding
     ...: =None)
Out[286]: 
array((0, 16, 250, 1, 0.053, 'RIG ', ' DIS ', 1, 48, 220, 2, 42, 241, 2, 43, 251, 3, 25, 266, 1, 36, 287, 2),
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<f8'), ('f5', '<U4'), ('f6', '<U5'), ('f7', '<i8'), ('f8', '<i8'), ('f9', '<i8'), ('f10', '<i8'), ('f11', '<i8'), ('f12', '<i8'), ('f13', '<i8'), ('f14', '<i8'), ('f15', '<i8'), ('f16', '<i8'), ('f17', '<i8'), ('f18', '<i8'), ('f19', '<i8'), ('f20', '<i8'), ('f21', '<i8'), ('f22', '<i8')])

现在,我将输入分解为具有23个字段的结构化数组,该数组又是int,float和(较小的)字符串的组合。

genfromtxt让我定义了一个dtype,可以将子字段分组在一起。

例如,仅尝试处理前6列:

In [298]: dt = np.dtype([('f0','i'),('f1','i',2),('f2','i'),('f3','i'),('f4','U3
     ...: ')])
In [299]: np.genfromtxt([foo(a) for a in txt],delimiter=',',dtype=dt, encoding=N
     ...: one,usecols=range(6))
Out[299]: 
array((0, [ 16, 250], 1, 0, 'RIG'),
      dtype=[('f0', '<i4'), ('f1', '<i4', (2,)), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<U3')])

我将'16,250'分组为一个包含2个整数的字段。后来的'48,220; 2,42,241; 2'可以嵌套3个字段(由';'定义),并且可以嵌套在这些2,2和1个子字段中。

genfromtxt接受另一种定界符形式-固定的字段宽度。


从速度上看,genfromtxt在滚动自己的位置方面没有任何改进。它仍然必须读取每一行,将其拆分,然后将值收集到列表列表中。最后,它将其转换为数组。

pandas拥有更快的csv阅读器,但是这种情况下使用起来可能太复杂了。 engine=python参数强制其使用较慢的所有python版本。