我试图使用python打开文件格式,对于这个文件,我选择使用pandas(速度和可用性)。
(我将在下面附上完整代码) 用于读取文件的代码段是:
with open( filename, "rb") as fd:
hdr={}
while True:
pos = fd.tell()
line = fd.readline().split()
if line[0] == "SPACE":
break
key=line[0]
for value in line[1:]:
hdr.setdefault(key, []).append(value)
用它读取文本文件头。 while循环pos
之后有一个位置,其中找到了第一个非标题结构(由SPACE
文本标记)。该文件将包含许多空间结构(只是一堆数字)。
然后我做了一个小倒带fd.seek(pos)
并开始读取数据本身(空间)
# Building the header
self.header = {
[...]
'nospaces' : int(hdr['NOSPACES'][0]),
'objects' : hdr['OBJECT']
}
# Probably there is a best way to do this
[...]
self.nospaces = self.header['nospaces']
self.objects = self.header['objects']
fd.seek(pos)
self.space=[]
# Im using range(1) for sake of test
for i in range(1): #range(self.nospaces):
self.space.append(lambda:0)
line = fd.readline().split()
# In the first line of SPACE we find a line like this:
# SPACE 29768 s1_0411_sa
# Where 28768 is the number of text lines of this space data
# s1_0411_sa is the space title/name
self.space[i].lines = int(line[1])
self.space[i].name = line[2]
self.space[i].data = pd.read_csv(fd,
delim_whitespace=True,
header=None,
names=self.objects,
nrows=self.space[i].lines, # Here I read the exact number of lines
index_col=(0,1),
dtype="float32")
但在那之后跑了一个:
fd.tell()
fd.readline()
我没有给我回复下一个SPACE结构数据(因为我希望pandas能够完全读取我要求它的行数)而不是tt让我回到这个位置:1310868
和下一行在第二个空间结构之后很长一段随机线的中间。试着理解为什么我得到这个号码:
(1310868-148)/2**16 = 20
。
我认为,pandas读取缓冲区越来越大,并通过下一个条目。
我不想多次读取文件,一个用于查找空间结构,另一个用于将结构映射到pandas数据帧。
我的问题是,如何让pandas在读取29768空格行后立即停止并返回我的文件描述符。 (s1.space [0] .lines上的值。)
如果没有办法告诉大熊猫,我怎样才能在不读取文件两次或重新映射文件的情况下实现这一目标(我想避免内存中的数据重复),因为这些文件可能很大?
遵循完整的可运行代码:
#!/usr/bin/env python
import pandas as pd
class space:
def read(self, filename):
with open( filename, "rb") as fd:
hdr={}
while True:
pos = fd.tell()
line = fd.readline().split()
if line[0] == "SPACE":
break
key=line[0]
for value in line[1:]:
hdr.setdefault(key, []).append(value)
# Building the header
self.header = {
'x0' : int(hdr['XAXIS'][0]),
'xinc' : int(hdr['XAXIS'][1]),
'xmax' : int(hdr['XAXIS'][2]),
'y0' : int(hdr['YAXIS'][0]),
'yinc' : int(hdr['YAXIS'][1]),
'ymax' : int(hdr['YAXIS'][2]),
'nospaces' : int(hdr['NOSPACES'][0]),
'objects' : hdr['OBJECT']
}
# Probably there is a best way to do this
self.x0 = self.header['x0']
self.xinc = self.header['xinc']
self.xmax = self.header['xmax']
self.y0 = self.header['y0']
self.yinc = self.header['yinc']
self.ymax = self.header['ymax']
self.nospaces = self.header['nospaces']
self.objects = self.header['objects']
print fd.tell()
fd.seek(pos)
self.space=[]
for i in range(1): #range(self.nospaces):
self.space.append(lambda:0)
line = fd.readline().split()
self.space[i].lines = int(line[1])
self.space[i].name = line[2]
self.space[i].data = pd.read_csv(fd,
delim_whitespace=True,
header=None,
names=self.objects,
nrows=self.space[i].lines,
index_col=(0,1),
dtype="float32")
# This tell() goes far below the self.space[i].lines read.
print fd.tell()
print fd.readline()
if __name__ == "__main__":
s1=space()
s1.read("data.txt")
数据文件如下所示:
XAXIS 1525 2 1767
YAXIS 1525 2 2011
NOBJECTS 5
NOSPACES 2
OBJECT YAXIS
OBJECT XAXIS
OBJECT XCOORD
OBJECT YCOORD
OBJECT DEPTH
SPACE 29768 s1_0411_sa
1525 1525 125000.01 125000.01 5933.09
1525 1527 125164.05 125000.01 5870.35
[...] then more 29766 lines [...]
SPACE 29768 s2_0411_sa
1525 1525 125000.01 125000.01 19171.9
1525 1527 125164.05 125000.01 18967.5
1525 1529 125328.09 125000.01 18724.8
[...] more 29765 lines [...]