我尝试搜索这个问题,但我找不到那些看似不太复杂的答案。
我正在从只有空格分隔符的文件中读取。列不是固定宽度。前两列是给我这个问题的。它是15列,前两个是字符串,其他一切都是浮点数。
我尝试使用numpy" genfromtxt"并指定了dtype。但是,某些字符串条目为空或包含数字,因此这些行被误读为具有15或17个条目。
以下是几行线的示例。
NGC 104 47 Tuc 00 24 05.67 -72 04 52.6 305.89 -44.89 4.5 7.4 1.9 -2.6 -3.1
NGC 288 00 52 45.24 -26 34 57.4 152.30 -89.38 8.9 12.0 -0.1 0.0 -8.9
NGC 362 01 03 14.26 -70 50 55.6 301.53 -46.25 8.6 9.4 3.1 -5.1 -6.2
Whiting 1 02 02 57 -03 15 10 161.22 -60.76 30.1 34.5 -13.9 4.7 -26.3
我该如何处理?我应该重新格式化文本,然后将其输出为CSV格式吗?我应该读作正则表达式吗?我可以修复此命令:
data = np.genfromtxt('PositionalData.txt', skiprows=0, missing_values=(' '), dtype=['S6','S6', 'f4', 'f4', 'f4', 'f4', 'f4', 'f4', 'f5','f4','f4', 'f4', 'f4', 'f4', 'f4'])
谢谢,非常感谢帮助。
编辑:
使用一些固定宽度设置后,这是一些输出:
(' NG', 'C 1', 0.0, 4.0, nan, nan, nan, nan, 4.0, 7.0, nan, nan, nan, nan, nan)
(' NG', 'C 2', 8.0, 8.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan)
(' NG', 'C 3', 6.0, 2.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan)
(' Wh', 'iti', nan, nan, nan, 1.0, nan, nan, nan, nan, nan, nan, nan, nan, nan)
(' NG', 'C 1', 2.0, 6.0, 1.0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan)
(' Pa', 'l 1', nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan)
命令为data = np.genfromtxt('PositionalDataTest.txt', skiprows=0,delimiter=(3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), missing_values=(' '), dtype=['S7','S7', 'f4', 'f4', 'f4', 'f4', 'f4', 'f4', 'f5','f4','f4', 'f4', 'f4', 'f4', 'f4'])
这些行是:
NGC 104 47 Tuc 00 24 05.67 -72 04 52.6 305.89 -44.89 4.5 7.4 1.9 -2.6 -3.1
NGC 288 00 52 45.24 -26 34 57.4 152.30 -89.38 8.9 12.0 -0.1 0.0 -8.9
NGC 362 01 03 14.26 -70 50 55.6 301.53 -46.25 8.6 9.4 3.1 -5.1 -6.2
Whiting 1 02 02 57 -03 15 10 161.22 -60.76 30.1 34.5 -13.9 4.7 -26.3
NGC 1261 03 12 16.21 -55 12 58.4 270.54 -52.12 16.3 18.1 0.1 -10.0 -12.9
Pal 1 03 33 20.04 79 34 51.8 130.06 19.03 11.1 17.2 -6.8 8.1 3.6
答案 0 :(得分:2)
考虑数据文件的这一部分:
-72 04 52.6
-26 34 57.4
-70 50 55.6
-03 15 10
-55 12 58.4
79 34 51.8
可以这样解析:
In [75]: np.genfromtxt('data2', delimiter=[3,3,5], dtype=None).tolist()
Out[75]:
[(-72, 4, 52.6),
(-26, 34, 57.4),
(-70, 50, 55.6),
(-3, 15, 10.0),
(-55, 12, 58.4),
(79, 34, 51.8)]
可以类似地解析文件的其余部分,难点在于找到要在delimiter
中使用的正确列宽。
这很费力,我宁愿不这样做,因为这个解决方案很脆弱。 使用固定宽度的列很可能无法解析您的数据。
因此,让我们拍摄一个强大的解决方案。 np.genfromtxt
可以接受任何可迭代的字符串作为其第一个参数。
因此,我们可以通过简单地定义生成器函数来预处理文件中的行,从而充分利用Python字符串操作来解决问题。
我们为所有这些功能付出的代价是,每行调用一次Python函数将比使用简单分隔符或固定宽度列解析文件时使用的C代码np.genfromtxt
慢得多。
import numpy as np
def process(iterable):
for line in iterable:
parts = [line[:11], line[11:24]] + line[24:].split()
yield '@'.join(parts)
with open('data', 'rb') as f:
data = np.genfromtxt(process(f), dtype=None, delimiter='@')
print(repr(data))
产量
array([ ('NGC 104 ', '47 Tuc ', 0, 24, 5.67, -72, 4, 52.6, 305.89, -44.89, 4.5, 7.4, 1.9, -2.6, -3.1),
('NGC 288 ', ' ', 0, 52, 45.24, -26, 34, 57.4, 152.3, -89.38, 8.9, 12.0, -0.1, 0.0, -8.9),
('NGC 362 ', ' ', 1, 3, 14.26, -70, 50, 55.6, 301.53, -46.25, 8.6, 9.4, 3.1, -5.1, -6.2),
('Whiting 1 ', ' ', 2, 2, 57.0, -3, 15, 10.0, 161.22, -60.76, 30.1, 34.5, -13.9, 4.7, -26.3),
('NGC 1261 ', ' ', 3, 12, 16.21, -55, 12, 58.4, 270.54, -52.12, 16.3, 18.1, 0.1, -10.0, -12.9),
('Pal 1 ', ' ', 3, 33, 20.04, 79, 34, 51.8, 130.06, 19.03, 11.1, 17.2, -6.8, 8.1, 3.6)],
dtype=[('f0', 'S11'), ('f1', 'S13'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<f8'), ('f5', '<i8'), ('f6', '<i8'), ('f7', '<f8'), ('f8', '<f8'), ('f9', '<f8'), ('f10', '<f8'), ('f11', '<f8'), ('f12', '<f8'), ('f13', '<f8'), ('f14', '<f8')])
请注意,process
函数使用'@'
作为列之间的分隔符。如果数据包含'@'
,则必须为分隔符选择其他字符。