nixy中unix cut -c的等效行为?

时间:2017-09-01 17:35:52

标签: python numpy

当我使用bash时,我想剪切一个文本文件的一部分,我知道它在哪一行,我使用这样的东西:

X=$(sed -n ''$j'p' FINAL.CRD | cut -c 23-37)

那是因为我通常知道我需要的信息在哪里,在这种情况下,在23和37之间。

我正在尝试使用python执行相同操作,但我没有找到如何使用np.loadtxt

执行此操作

我的文字文件是这样的:

IMPZ               3  WWA        3.06  4.51  7.32
MTSF               2  W W        1.52  1.72  0.18
PI01               2   AA        4.02  3.32 10.26
PI02               2  A A        4.58  2.29  0.40

我想得到3.06,1.52,4.02,4.58。但是,有时文件显示“WWA”或“W W”,因此,我无法使用usecols。但是我知道这个数字总是在哪一行,这就是为什么我想要一些像cut -c这样的字符/字节偏移的东西。

2 个答案:

答案 0 :(得分:4)

有关此np.loadtxt解决方案的信息,请转到Jon Clements:

np.loadtxt('FINAL.CRD', usecols=-3)返回每行末尾的第三个字段(默认情况下,空格用作分隔符):

In [193]: np.loadtxt('FINAL.CRD', usecols=-3)
Out[193]: array([ 3.06,  1.52,  4.02,  4.58])

即使文件在每一行上可能包含不同数量的字段,只要您要查找的值可以表示为"来自结尾的第三个字段",然后{{1}能做好这件事。

以下是使用NumPy 读取具有固定宽度字段的文件的方法:

np.genfromtxt可以通过指定np.loadtxt('FINAL.CRD', usecols=-3)的整数(宽度)列表来读取具有固定宽度字段的文件:

delimeter

,其中

In [180]: np.genfromtxt('FINAL.CRD', dtype=None, delimiter=[22,37-22], usecols=[1])
Out[180]: 
array([b'WWA        3.06', b'W W        1.52', b' AA        4.02',
       b'A A        4.58'],
      dtype='|S15')

然而,使用% cat FINAL.CRD IMPZ 3 WWA 3.06 4.51 7.32 MTSF 2 W W 1.52 1.72 0.18 PI01 2 AA 4.02 3.32 10.26 PI02 2 A A 4.58 2.29 0.40 % sed -n ${j}p FINAL.CRD | cut -c 23-37 WWA 3.06 W W 1.52 AA 4.02 A A 4.58 指定列索引,使用cut -c指定np.genfromtxt参数中字段的宽度。因此,第一个字段(我们想要忽略)的宽度为22,第二个字段(我们想要的)的宽度为37-22。要仅抓取第二个字段,请指定delimiter

也许我误解了文件格式,但如果你想要usecols=[1], 然后给出你发布的文件,[ 3.06, 1.52, 4.02, 4.58]命令将是:

np.genfromtxt

答案 1 :(得分:3)

虽然在接受的答案中使用usecolsdelimiter是好的,但我认为这是一种更接近sed/cut的方法代码。

np.loadtxt接受任何给它行的输入。这包括一系列行。因此,我们可以加载文件cut,然后将其传递给loadtxt(或genfromtxt):

In [217]: with open('stack46005401.txt') as f: lines = f.readlines()
In [218]: lines
Out[218]: 
['IMPZ               3  WWA        3.06  4.51  7.32\n',
 'MTSF               2  W W        1.52  1.72  0.18\n',
 'PI01               2   AA        4.02  3.32 10.26\n',
 'PI02               2  A A        4.58  2.29  0.40\n']

然后使用标准的Python列表理解和字符串切片来获得所需的列

In [219]: [line[23:] for line in lines]
Out[219]: 
['WA        3.06  4.51  7.32\n',
 ' W        1.52  1.72  0.18\n',
 'AA        4.02  3.32 10.26\n',
 ' A        4.58  2.29  0.40\n']

并加载。通过对字符串切片的改进,我们甚至不需要usecols

In [220]: np.loadtxt(_, usecols=[1])   # _ is the output in Out[219]
Out[220]: array([ 3.06,  1.52,  4.02,  4.58])

这个读取和过滤器在文本文件需要修改的许多情况下都很有用,然后才能将其作为正确的csv读取。