仅使用python读取csv文件中的某些行

时间:2019-05-22 13:51:27

标签: python csv

我只想读取整个csv文件中从csv文件中的某一行开始的特定数量的行,而无需进行迭代以达到该特定点。

让我们说我有一个100行的csv文件,我只想读取50到60行。我不想从1到49遍历到50行开始读取。我可以通过seek()以某种方式实现这一目标吗?

例如: 寻求第50行 从50读到60

下一次: 寻求第27行 阅读27至34 等等

因此,不仅要在文件中连续搜索,而且要向后搜索。

非常感谢

5 个答案:

答案 0 :(得分:3)

一个选择是使用熊猫。例如:

import pandas as pd
# Select file 
infile = r'path/file'
# Use skiprows to choose starting point and nrows to choose number of rows
data = pd.read_csv(infile, skiprows = 50, nrows=10)

答案 1 :(得分:2)

您可以使用 chunksize ,我比较讨厌,但是您可以尝试

import pandas as pd

chunksize = 10 ** 6
for chunk in pd.read_csv(filename, chunksize=chunksize):
    process(chunk)

答案 2 :(得分:2)

正如其他人所说,最明显的解决方案是使用读csv的熊猫! 该方法有一个名为skiprows的参数:

from the doc说了些什么:

skiprows:类似列表,int或可调用的列表,可选 在文件开始处要跳过的行号(索引为0)或要跳过的行数(整数)。

如果可调用,将根据行索引评估可调用函数,如果应跳过该行,则返回True,否则返回False。有效的可调用参数的示例为lambda x:[0,2]中的x。

您可以拥有这样的东西:

import pandas as pd
data = pd.read_csv('path/to/your/file', skiprows =lambda x: x not in range(50, 60))

由于您指定了内存问题,因此可以使用this tutorial

中所述的chunksize参数

他说:

  

该参数本质上表示要读入的行数   数据帧在任何时候都可以容纳到本地存储器中。   由于数据包含超过7000万行,因此我指定   每次破坏大数据时的块大小为一百万行   分成很多小块。

df_chunk = pd.read_csv(r'../input/data.csv', chunksize=1000000)

您可以尝试此操作并遍历块以仅检索您要查找的行。

如果行号在指定列表中,则该函数应返回true

答案 3 :(得分:2)

如果列数/行长度的变量是可变的,那么在不“读取”(即处理)之前文件的每个字符并计算行终止符的情况下,不可能找到所需的行。在python中处理它们的最快方法是使用迭代。

关于处理大文件的最快方法,我不知道用这种方式逐行迭代是否更快:

with open(file_name) as f:
    for line,_ in zip(f, range(50)):
        pass
    lines = [line for line,_ in zip(f, range(10))]

...或使用seek一次读取一个字符,并计算换行符。但这当然更方便。

但是,如果文件被大量读取,则随着时间的推移,遍历各行将变得很慢。如果文件内容没有更改,您可以改为读取一次整个内容并提前建立dict行长:

from itertools import accumulate
with open(file_name) as f:
    cum_lens = dict(enumerate(accumulate(len(line) for line in f), 1))

这将使您可以查找文件中的任何行号,而无需再次处理整个内容:

def seek_line(path, line_num, cum_lens):
    with open(path) as f:
        f.seek(cum_lens[line_num], 0)
        return f.readline()

class LineX:
    """A file reading object that can quickly obtain any line number."""
    def __init__(self, path, cum_lens):
        self.cum_lens = cum_lens
        self.path = path
    def __getitem__(self, i):
        return seek_line(self.path, i, self.cum_lens)

linex = LineX(file_name, cum_lens)
line50 = linex[50]

但是,此时,最好将文件内容加载到某种数据库中。我取决于您要执行的操作以及文件包含的数据类型。

答案 4 :(得分:0)

很简单:

with open("file.csv", "r") as file:
    print(file.readlines()[50:60])