在单个文件上使用多个 genfromtxt
Using multiple genfromtxt on a single file
我是 Python 的新手,目前在处理我的输入文件读取时遇到问题。基本上我希望我的代码采用一个输入文件,其中相关信息包含在 4 行的块中。对于我的特定目的,我只关心每个块的第 1-3 行中的信息。
我正在处理的输入的两块示例如下:
#Header line 1
#Header line 2
'Mn 1', 5130.0059, -2.765, 5.4052, 2.5, 7.8214, 1.5, 1.310, 2.390, 0.500, 8.530,-5.360,-7.630,
' LS 3d6.(5D).4p z6F*'
' LS 3d6.(5D).4d e6F'
'K07 A Kurucz MnI 2007 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 Mn '
'Fe 2', 5130.0127, -5.368, 7.7059, 2.5, 10.1221, 2.5, 1.030, 0.860, 0.940, 8.510,-6.540,-7.900,
' LS 3d6.(3F2).4p y4F*'
' LS 3d5.4s2 2F2'
'RU Kurucz FeII 2013 4 K13 5 RU 4 K13 4 K13 4 K13 4 K13 4 K13 4 K13 4 K13 Fe+ '
我更愿意将这三行中每一行的信息存储在单独的数组中。由于条目是字符串和浮点数的混合,我使用 Numpy.genfromtxt 来读取输入文件,如下所示:
import itertools
import numpy as np
with open(input_file) as f_in:
#Opening file, reading every fourth line starting with line 2.
data = np.genfromtxt(itertools.islice(f_in,2,None,4),dtype=None,delimiter=",")
#Storing lower transition designation:
low = np.genfromtxt(itertools.islice(f_in,3,None,4),dtype=str)
#Storing upper transition designation:
up = np.genfromtxt(itertools.islice(f_in,4,None,4),dtype=str)
执行代码后,genfromtxt 第一次正确读取了文件中的信息。但是,对于 genfromtxt 的第二次和第三次调用,我收到以下警告
UserWarning: genfromtxt: Empty input file: "<itertools.islice object at 0x102d7a1b0>"
warnings.warn('genfromtxt: Empty input file: "%s"' % fname)
虽然这只是一个警告,但第二次和第三次调用 genfromtxt 返回的数组是空的,并且不包含预期的字符串。如果我注释掉 genfromtxt 的第二次和第三次调用,代码将按预期运行。
据我了解,以上内容应该有效,但我有点不知所措,为什么它不起作用。想法?
试试这个:
with open(input_file) as f_in:
#Opening file, reading every fourth line starting with line 2.
lines = f_in.readlines()
data = np.genfromtxt(lines[2::4],dtype=None,delimiter=",")
#Storing lower transition designation:
low = np.genfromtxt(lines[3::4],dtype=str)
#Storing upper transition designation:
up = np.genfromtxt(lines[4::4],dtype=str)
我没怎么用过 islice
,但 itertools
往往是生成器,它会迭代到最后。重复调用它们时必须小心。您也许可以让 islice
与 tee
或 repeat
一起工作。但我认为最简单的是获取行列表,然后使用普通索引选择相关行。
示例tee
:
with open('myfile.txt') as f:
its = itertools.tee(f,2)
print(list(itertools.islice(its[0],0,None,2)))
print(list(itertools.islice(its[1],1,None,2)))
现在文件被读取一次,但可以迭代两次。
在第一个 genfromtext
(好吧,实际上是 islice
)之后,文件迭代器到达了文件末尾。因此警告和空数组:后两个 islice
调用使用空迭代器。
您需要像 一样使用 f_in.readlines()
将文件读入内存 line-by-line,或者在后续读取之前添加 f_in.seek(0)
以重置文件指向输入开始的指针。这是一个稍微 memory-friendly 的解决方案,如果这些文件真的很大,这可能很重要。
# Note: Untested code follows
with open(input_file) as f_in:
np.genfromtxt(itertools.islice(f_in,2,None,4),dtype=None,delimiter=",")
f_in.seek(0) # Set the file pointer back to the beginning
low = np.genfromtxt(itertools.islice(f_in,3,None,4),dtype=str)
f_in.seek(0) # Set the file pointer back to the beginning
up = np.genfromtxt(itertools.islice(f_in,4,None,4),dtype=str)
我是 Python 的新手,目前在处理我的输入文件读取时遇到问题。基本上我希望我的代码采用一个输入文件,其中相关信息包含在 4 行的块中。对于我的特定目的,我只关心每个块的第 1-3 行中的信息。
我正在处理的输入的两块示例如下:
#Header line 1
#Header line 2
'Mn 1', 5130.0059, -2.765, 5.4052, 2.5, 7.8214, 1.5, 1.310, 2.390, 0.500, 8.530,-5.360,-7.630,
' LS 3d6.(5D).4p z6F*'
' LS 3d6.(5D).4d e6F'
'K07 A Kurucz MnI 2007 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 1 K07 Mn '
'Fe 2', 5130.0127, -5.368, 7.7059, 2.5, 10.1221, 2.5, 1.030, 0.860, 0.940, 8.510,-6.540,-7.900,
' LS 3d6.(3F2).4p y4F*'
' LS 3d5.4s2 2F2'
'RU Kurucz FeII 2013 4 K13 5 RU 4 K13 4 K13 4 K13 4 K13 4 K13 4 K13 4 K13 Fe+ '
我更愿意将这三行中每一行的信息存储在单独的数组中。由于条目是字符串和浮点数的混合,我使用 Numpy.genfromtxt 来读取输入文件,如下所示:
import itertools
import numpy as np
with open(input_file) as f_in:
#Opening file, reading every fourth line starting with line 2.
data = np.genfromtxt(itertools.islice(f_in,2,None,4),dtype=None,delimiter=",")
#Storing lower transition designation:
low = np.genfromtxt(itertools.islice(f_in,3,None,4),dtype=str)
#Storing upper transition designation:
up = np.genfromtxt(itertools.islice(f_in,4,None,4),dtype=str)
执行代码后,genfromtxt 第一次正确读取了文件中的信息。但是,对于 genfromtxt 的第二次和第三次调用,我收到以下警告
UserWarning: genfromtxt: Empty input file: "<itertools.islice object at 0x102d7a1b0>"
warnings.warn('genfromtxt: Empty input file: "%s"' % fname)
虽然这只是一个警告,但第二次和第三次调用 genfromtxt 返回的数组是空的,并且不包含预期的字符串。如果我注释掉 genfromtxt 的第二次和第三次调用,代码将按预期运行。
据我了解,以上内容应该有效,但我有点不知所措,为什么它不起作用。想法?
试试这个:
with open(input_file) as f_in:
#Opening file, reading every fourth line starting with line 2.
lines = f_in.readlines()
data = np.genfromtxt(lines[2::4],dtype=None,delimiter=",")
#Storing lower transition designation:
low = np.genfromtxt(lines[3::4],dtype=str)
#Storing upper transition designation:
up = np.genfromtxt(lines[4::4],dtype=str)
我没怎么用过 islice
,但 itertools
往往是生成器,它会迭代到最后。重复调用它们时必须小心。您也许可以让 islice
与 tee
或 repeat
一起工作。但我认为最简单的是获取行列表,然后使用普通索引选择相关行。
示例tee
:
with open('myfile.txt') as f:
its = itertools.tee(f,2)
print(list(itertools.islice(its[0],0,None,2)))
print(list(itertools.islice(its[1],1,None,2)))
现在文件被读取一次,但可以迭代两次。
在第一个 genfromtext
(好吧,实际上是 islice
)之后,文件迭代器到达了文件末尾。因此警告和空数组:后两个 islice
调用使用空迭代器。
您需要像 f_in.readlines()
将文件读入内存 line-by-line,或者在后续读取之前添加 f_in.seek(0)
以重置文件指向输入开始的指针。这是一个稍微 memory-friendly 的解决方案,如果这些文件真的很大,这可能很重要。
# Note: Untested code follows
with open(input_file) as f_in:
np.genfromtxt(itertools.islice(f_in,2,None,4),dtype=None,delimiter=",")
f_in.seek(0) # Set the file pointer back to the beginning
low = np.genfromtxt(itertools.islice(f_in,3,None,4),dtype=str)
f_in.seek(0) # Set the file pointer back to the beginning
up = np.genfromtxt(itertools.islice(f_in,4,None,4),dtype=str)