【问题标题】:seek() not working properly, although file opened in "r" modeseek() 无法正常工作,尽管文件以“r”模式打开
【发布时间】:2018-05-21 21:29:21
【问题描述】:

我有一个包含日期和浮点数的 CSV 文件(日、月、年、浮点数)。这是示例,

1,1,2000,4076.79
2,1,2000,1216.82
3,1,2000,1299.68
4,1,2000,637.36
5,1,2000,3877.91
6,1,2000,3308.99
7,1,2000,2925.93
8,1,2000,1559.09
9,1,2000,3190.81
10,1,2000,3008.66
11,1,2000,2026.35
12,1,2000,3279.61
13,1,2000,3601.6
14,1,2000,2021.1
15,1,2000,2103.62
16,1,2000,609.64
17,1,2000,633.16
18,1,2000,1195.34

我想先读第一行,然后读最后一行:

handle = open(getInputFileName(), "r")

getInputFileName() 观察。是一个返回文件名的函数。那么,

print "numberlines", numberLines        #DEBUG# 
>>> 3660

numberLines 是文件中的行数。那么,

handle.seek(0)
lineData = handle.readline().split(",")
print lineData      #DEBUG#
>>> ['1','1','2000','4076.79\n']

直到这里一切正常。但是,

handle.seek(numberLines-1)
lineData = handle.readline().split(",")
print lineData      #DEBUG#
>>>['7', '7', '2000', '2347.51\n']

但实际上文件的最后一行是31,12,2009,3823.02 为什么不寻求一路下降? 我尝试删除卡住的行,但随后程序崩溃了ValueError: could not convert string to float:(然后我使用 lineData 作为浮点数):

newestDate.insert(1,float(lineData[1]))

如果行有问题,我检查了文件,但格式从未改变。为什么我的代码在第一行而不是最后一行?

【问题讨论】:

标签: python python-2.7 csv file-io seek


【解决方案1】:

file.seek(offset[, whence]) 对文件内的字节位置进行操作。不是行号。如果要对行进行操作,请使用 readline() 或迭代文件:

with ("file.txt", "r") as f:
    first = next(f) # see comment Jean-François Fabre
    for last in f:  # and tdelanys comment :o)
        pass # do nothing with all other lines, last will hold the last one  

现在firstlast 分别保存第一行和最后一行。

这里的好处是您可以在内存中最多保存 1 行文本,然后丢弃其余的。 AFAIK 没有单步执行就无法简单地获取文件的第一行和最后一行。

如果您想解析数据,请按照DyZ suggestion 使用 csv 模块和阅读器 - 它更安全。如果你喜欢冒险 - 去pandas,它有大量的内置 csv 功能:) 并且能够读取大 csv 的分块以对内存更友好(参见 f.e.How to read a 6 GB csv file with pandas

【讨论】:

  • first = next(f) 获取第一行更智能
  • for last in f: pass 应该可以。
  • 你可以得到最后一行,但你需要寻找到最后,然后逐个字符地寻找,直到找到位置 0 或换行。如果文件很大,可能会很有趣:stackoverflow.com/questions/7167008/…
【解决方案2】:

不要手动读取 CSV 文件(如果在一行中有任何带逗号的引用项目,您的代码将失败,例如 ...,"1,2000",...)。有一个 CSV 阅读器:

import csv
with open("foo.csv") as infile:
    reader = csv.reader(infile)
    data = list(reader)

data[0] # First
# ['1', '1', '2000', '4076.79']
data[-1] # Last
#['18', '1', '2000', '1195.34']

如果内存有问题,请阅读第一行,跳过文件的其余部分,并保留最后一行,如另一个答案中所述。

【讨论】:

  • 您可以在reader 上应用帕特里克代码,这样您就不必加载所有数据
  • 我认为这更快...如果你能负担得起内存:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多