【发布时间】:2010-12-18 13:25:24
【问题描述】:
我们有一个大的原始数据文件,我们希望将其修剪为指定的大小。
如何在 python 中获取文本文件的前 N 行?正在使用的操作系统会对实现产生任何影响吗?
【问题讨论】:
-
我可以给 n 作为命令行参数吗
我们有一个大的原始数据文件,我们希望将其修剪为指定的大小。
如何在 python 中获取文本文件的前 N 行?正在使用的操作系统会对实现产生任何影响吗?
【问题讨论】:
Python 2:
with open("datafile") as myfile:
head = [next(myfile) for x in xrange(N)]
print head
Python 3:
with open("datafile") as myfile:
head = [next(myfile) for x in range(N)]
print(head)
这是另一种方式(Python 2 和 3):
from itertools import islice
with open("datafile") as myfile:
head = list(islice(myfile, N))
print(head)
【讨论】:
N = 10
with open("file.txt", "a") as file: # the a opens it in append mode
for i in range(N):
line = next(file).strip()
print(line)
【讨论】:
r 确实是更合乎逻辑的选择,我认为。
如果您想快速阅读第一行并且不关心性能,可以使用.readlines(),它返回列表对象,然后对列表进行切片。
例如对于前 5 行:
with open("pathofmyfileandfileandname") as myfile:
firstNlines=myfile.readlines()[0:5] #put here the interval you want
注意:整个文件被读取,所以从性能的角度来看不是最好的,但它 易于使用,书写速度快,易于记忆,所以如果你只想表演 一些一次性计算很方便
print firstNlines
与其他答案相比,一个优势是可以轻松选择行的范围,例如跳过前 10 行 [10:30] 或最后 10 行 [:-10] 或只取偶数行 [::2]。
【讨论】:
我所做的是使用pandas 调用N 行。我认为性能不是最好的,但是例如如果N=1000:
import pandas as pd
yourfile = pd.read_csv('path/to/your/file.csv',nrows=1000)
【讨论】:
nrows 选项,它可以设置为1000 并且不加载整个文件。 pandas.pydata.org/pandas-docs/stable/generated/… 总的来说,pandas 对大文件有这个和其他节省内存的技术。
sep 来定义列分隔符(不应出现在非 csv 文件中)
pandas.read() 函数,您知道有关该主题的任何信息吗?
没有特定的方法来读取文件对象公开的行数。
我想最简单的方法是:
lines =[]
with open(file_name) as f:
lines.extend(f.readline() for i in xrange(N))
【讨论】:
两种最直观的方法是:
逐行迭代文件,break 在N 行之后。
使用next() 方法N 逐行迭代文件。 (这本质上只是顶级答案的不同语法。)
代码如下:
# Method 1:
with open("fileName", "r") as f:
counter = 0
for line in f:
print line
counter += 1
if counter == N: break
# Method 2:
with open("fileName", "r") as f:
for i in xrange(N):
line = f.next()
print line
底线是,只要您不使用readlines() 或enumerate 将整个文件放入内存,您就有很多选择。
【讨论】:
基于 gnibbler 最高投票答案(2009 年 11 月 20 日 0:27):此类将 head() 和 tail() 方法添加到文件对象。
class File(file):
def head(self, lines_2find=1):
self.seek(0) #Rewind file
return [self.next() for x in xrange(lines_2find)]
def tail(self, lines_2find=1):
self.seek(0, 2) #go to end of file
bytes_in_file = self.tell()
lines_found, total_bytes_scanned = 0, 0
while (lines_2find+1 > lines_found and
bytes_in_file > total_bytes_scanned):
byte_block = min(1024, bytes_in_file-total_bytes_scanned)
self.seek(-(byte_block+total_bytes_scanned), 2)
total_bytes_scanned += byte_block
lines_found += self.read(1024).count('\n')
self.seek(-total_bytes_scanned, 2)
line_list = list(self.readlines())
return line_list[-lines_2find:]
用法:
f = File('path/to/file', 'r')
f.head(3)
f.tail(3)
【讨论】:
我自己最方便的方式:
LINE_COUNT = 3
print [s for (i, s) in enumerate(open('test.txt')) if i < LINE_COUNT]
基于List Comprehension的解决方案 函数 open() 支持迭代接口。 enumerate() 覆盖 open() 并返回元组(索引,项目),然后我们检查我们是否在可接受的范围内(如果 i
享受 Python。 ;)
【讨论】:
[next(file) for _ in range(LINE_COUNT)] 稍微复杂一些。
对于前 5 行,只需执行以下操作:
N=5
with open("data_file", "r") as file:
for i in range(N):
print file.next()
【讨论】:
如果您想要一些显然(无需在手册中查找深奥的东西)无需导入和 try/except 且适用于相当范围的 Python 2.x 版本(2.2 到 2.6)的东西:
def headn(file_name, n):
"""Like *x head -N command"""
result = []
nlines = 0
assert n >= 1
for line in open(file_name):
result.append(line)
nlines += 1
if nlines >= n:
break
return result
if __name__ == "__main__":
import sys
rval = headn(sys.argv[1], int(sys.argv[2]))
print rval
print len(rval)
【讨论】:
如果您有一个非常大的文件,并且假设您希望输出是一个 numpy 数组,则使用 np.genfromtxt 将冻结您的计算机。根据我的经验,这要好得多:
def load_big_file(fname,maxrows):
'''only works for well-formed text file of space-separated doubles'''
rows = [] # unknown number of lines, so use list
with open(fname) as f:
j=0
for line in f:
if j==maxrows:
break
else:
line = [float(s) for s in line.split()]
rows.append(np.array(line, dtype = np.double))
j+=1
return np.vstack(rows) # convert list of vectors to array
【讨论】:
这对我有用
f = open("history_export.csv", "r")
line= 5
for x in range(line):
a = f.readline()
print(a)
【讨论】:
我想通过读取整个文件来处理少于 n 行的文件
def head(filename: str, n: int):
try:
with open(filename) as f:
head_lines = [next(f).rstrip() for x in range(n)]
except StopIteration:
with open(filename) as f:
head_lines = f.read().splitlines()
return head_lines
这要归功于 John La Rooy 和 Ilian Iliev。使用带有异常句柄的函数以获得最佳性能
修订 1:感谢 FrankM 的反馈,我们可以进一步添加处理文件存在和读取权限
import errno
import os
def head(filename: str, n: int):
if not os.path.isfile(filename):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), filename)
if not os.access(filename, os.R_OK):
raise PermissionError(errno.EACCES, os.strerror(errno.EACCES), filename)
try:
with open(filename) as f:
head_lines = [next(f).rstrip() for x in range(n)]
except StopIteration:
with open(filename) as f:
head_lines = f.read().splitlines()
return head_lines
您可以使用第二个版本,也可以使用第一个版本并稍后处理文件异常。从性能角度来看,检查速度很快,而且几乎没有问题
【讨论】:
islice 执行相同的操作(读取整个文件,当它的行数较少时)。但是您的解决方案比变体 1 和 2 更好。
这是另一个不错的解决方案,list comprehension:
file = open('file.txt', 'r')
lines = [next(file) for x in range(3)] # first 3 lines will be in this list
file.close()
【讨论】:
从 Python 2.6 开始,您可以利用 IO 基类中更复杂的函数。所以上面评分最高的答案可以改写为:
with open("datafile") as myfile:
head = myfile.readlines(N)
print head
(您不必担心文件少于 N 行,因为不会引发 StopIteration 异常。)
【讨论】:
lines,但参数引用bytes。
这适用于 Python 2 和 3:
from itertools import islice
with open('/tmp/filename.txt') as inf:
for line in islice(inf, N, N+M):
print(line)
【讨论】:
fname = input("Enter file name: ")
num_lines = 0
with open(fname, 'r') as f: #lines count
for line in f:
num_lines += 1
num_lines_input = int (input("Enter line numbers: "))
if num_lines_input <= num_lines:
f = open(fname, "r")
for x in range(num_lines_input):
a = f.readline()
print(a)
else:
f = open(fname, "r")
for x in range(num_lines_input):
a = f.readline()
print(a)
print("Don't have", num_lines_input, " lines print as much as you can")
print("Total lines in the text",num_lines)
【讨论】:
#!/usr/bin/python
import subprocess
p = subprocess.Popen(["tail", "-n 3", "passlist"], stdout=subprocess.PIPE)
output, err = p.communicate()
print output
这个方法对我有用
【讨论】:
使用 list(file_data)
将您的 CSV 文件对象简单地转换为列表import csv;
with open('your_csv_file.csv') as file_obj:
file_data = csv.reader(file_obj);
file_list = list(file_data)
for row in file_list[:4]:
print(row)
【讨论】: