我有一个包含行和列数据的文本文件(总共约17000行)。每列的长度都是统一的字符数,“未使用的”字符用空格填充。例如,第一列长度为11个字符,但该列中的最后四个字符始终为空格(因此,当使用文本编辑器查看时,它看起来是一个很好的列)。如果条目小于7个字符,有时它超过4个。
列之间没有用逗号,制表符或空格分隔。它们也不是所有相同数量的字符(前两个是11,后两个是8,最后一个是5 - 但是,有些是空格)。
如果第二列在其中包含字符串'OW',我想要做的是导入最后两列中的entires(数字)。任何帮助将不胜感激。
答案 0 :(得分:4)
Python的struct.unpack
可能是分割固定长度字段的最快方法。这是一个懒惰地读取您的文件并返回符合您标准的数字元组的函数:
import struct
def parsefile(filename):
with open(filename) as myfile:
for line in myfile:
line = line.rstrip('\n')
fields = struct.unpack('11s11s8s8s5s', line)
if 'OW' in fields[1]:
yield (int(fields[3]), int(fields[4]))
用法:
if __name__ == '__main__':
for field in parsefile('file.txt'):
print field
测试数据:
1234567890a1234567890a123456781234567812345
something maybe OW d 111111118888888855555
aaaaa bbbbb 1234 1212121233333
other thinganother OW 121212 6666666644444
输出:
(88888888, 55555)
(66666666, 44444)
答案 1 :(得分:3)
在Python中,您可以使用切片在已知位置提取子字符串 - 这通常使用list [start:end]语法完成。但是,您也可以创建切片对象,以后可以使用它们进行索引。
所以你可以这样做:
columns = [slice(11,22), slice(30,38), slice(38,44)]
myfile = open('some/file/path')
for line in myfile:
fields = [line[column].strip() for column in columns]
if "OW" in fields[0]:
value1 = int(fields[1])
value12 = int(fields[2])
....
将切片分成列表可以在数据格式发生变化时轻松更改代码,或者您需要对其他字段进行操作。
答案 2 :(得分:0)
entries = ((float(line[30:38]), float(line[38:43])) for line in myfile if "OW" in line[11:22])
for num1, num2 in entries:
# whatever
答案 3 :(得分:0)
这是一个可以帮助你的功能:
def rows(f, columnSizes):
while True:
row = {}
for (key, size) in columnSizes:
value = f.read(size)
if len(value) < size: # EOF
return
row[key] = value
yield row
有关如何使用的示例:
from StringIO import StringIO
sample = StringIO("""aaabbbccc
d e f
g h i
""")
for row in rows(sample, [('first', 3),
('second', 3),
('third', 4)]):
print repr(row)
请注意,与其他答案不同,此示例是不行分隔(它将文件纯粹用作字节的提供程序,而不是行的迭代器),因为您特别提到了字段没有分开,我以为行可能也不是;特别考虑了换行符。
您可以使用'in'运算符测试一个字符串是否是另一个字符串的子字符串。例如,
>>> 'OW' in 'hello'
False
>>> 'OW' in 'helOWlo'
True
所以在这种情况下,你可以做
if 'OW' in row['third']:
stuff()
但是您可以在任何值上测试任何字段。
答案 4 :(得分:-2)
entries = []
with open('my_file.txt', 'r') as f:
for line in f.read().splitlines()
line = line.split()
if line[1].find('OW') >= 0
entries.append( ( int(line[-2]) , int(line[-1]) ) )
entries是一个包含最后两个条目的元组的数组
编辑:oops