Numpy genfromtxt 读取额外不需要的字符串

Numpy genfromtxt reads additional unwanted strings

我想使用 numpy 的 genfromtxt 读取一个 txt 文件。文件 t.txt 如下所示:

###############
PSZ1 G096.89+24.17
PSZ1 G108.18−11.53
RXC J0225.1−2928
RXC J1053.7+5452
RXC J1234.2+0947
RXC J1314.4−2515
S 1081
ZwCl 0008.8+5215
ZwCl 2341+0000
1E 0657−558
1RXS J0603.3+4214
24P 73

我按如下方式导入 numpy 和 运行 genfromtxt:

import numpy as np
a =np.genfromtxt("t.txt", comments="#", dtype=None,autostrip=True,delimiter = " ")

并且 return 在发出 print a 时如下:

array([['PSZ1', 'G096.89+24.17'],
       ['PSZ1', 'G108.18\xe2\x88\x9211.53'],
       ['RXC', 'J0225.1\xe2\x88\x922928'],
       ['RXC', 'J1053.7+5452'],
       ['RXC', 'J1234.2+0947'],
       ['RXC', 'J1314.4\xe2\x88\x922515'],
       ['S', '1081'],
       ['ZwCl', '0008.8+5215'],
       ['ZwCl', '2341+0000'],
       ['1E', '0657\xe2\x88\x92558'],
       ['1RXS', 'J0603.3+4214'],
       ['24P', '73']], 
      dtype='|S15')

我想知道是什么原因导致包含 \x 的额外字符串以及如何在仍然使用 genfromtxt 的情况下摆脱它们。

此外,许多其他读取字符串的方法 return 同样的问题(额外的 \x 字符串),即使直接从这个 post (t.txt) 直接复制示例到 txt 或 csv 文件。

我在 atom 编辑器中创建了文件 t.txt,它在底部显示为 UTF8。我也将文件再次保存为UTF8。

如何正确读取 python 中错误编码的 + 和 - 符号,而无需手动单独更改它们?

谢谢

在 Py3 Ipython 会话中:

In [847]: data=np.genfromtxt('stack40159019.txt',comments='#',dtype=None)
In [848]: data
Out[848]: 
array([[b'PSZ1', b'G096.89+24.17'],
       [b'PSZ1', b'G108.18\xe2\x88\x9211.53'],
       [b'RXC', b'J0225.1\xe2\x88\x922928'],
       [b'RXC', b'J1053.7+5452'],
       [b'RXC', b'J1234.2+0947'],
       [b'RXC', b'J1314.4\xe2\x88\x922515'],
       [b'S', b'1081'],
       [b'ZwCl', b'0008.8+5215'],
       [b'ZwCl', b'2341+0000'],
       [b'1E', b'0657\xe2\x88\x92558'],
       [b'1RXS', b'J0603.3+4214'],
       [b'24P', b'73']], 
      dtype='|S15')
In [849]: np.char.decode(data)
Out[849]: 
array([['PSZ1', 'G096.89+24.17'],
       ['PSZ1', 'G108.18−11.53'],
       ['RXC', 'J0225.1−2928'],
       ['RXC', 'J1053.7+5452'],
       ['RXC', 'J1234.2+0947'],
       ['RXC', 'J1314.4−2515'],
       ['S', '1081'],
       ['ZwCl', '0008.8+5215'],
       ['ZwCl', '2341+0000'],
       ['1E', '0657−558'],
       ['1RXS', 'J0603.3+4214'],
       ['24P', '73']], 
      dtype='<U13')

建议的副本适用于 Py3,但我认为这种 decode 方法也适用于 Py2。

=====================

在 Py2 会话中:

>>> txt=b'G108.18\xe2\x88\x9211.53'
>>> txt
'G108.18\xe2\x88\x9211.53'
>>> txt.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 7: ordinal not in range(128)
>>> txt.decode('UTF-8')
u'G108.18\u221211.53'

>>> txt.decode(errors='replace')
u'G108.18\ufffd\ufffd\ufffd11.53'
>>> txt.decode(errors='ignore')
u'G108.1811.53'

并用 ascii 替换 unicode --:

>>> '\xe2\x88\x92'.decode('utf8')
u'\u2212'
>>> txt.decode('utf8').replace(u'\u2212','-')
u'G108.18-11.53'
>>> txt.decode('utf8').replace(u'\u2212','-').encode()
'G108.18-11.53'

因此 np.char.replace(回到 py3)

In [872]: np.char.replace(data1,u'\u2212','-').astype('S13')
Out[872]: 
array([[b'PSZ1', b'G096.89+24.17'],
       [b'PSZ1', b'G108.18-11.53'],
       [b'RXC', b'J0225.1-2928'],
       [b'RXC', b'J1053.7+5452'],
       [b'RXC', b'J1234.2+0947'],
       [b'RXC', b'J1314.4-2515'],
       [b'S', b'1081'],
       [b'ZwCl', b'0008.8+5215'],
       [b'ZwCl', b'2341+0000'],
       [b'1E', b'0657-558'],
       [b'1RXS', b'J0603.3+4214'],
       [b'24P', b'73']], 
      dtype='|S13')