获取csv文件的最后10000行

时间:2016-03-14 04:36:18

标签: python csv pandas tail

在pandas中,我可以使用pandas.io.parser.read_csv("file.csv", nrows=10000)获取csv文件的前10000行。

但是因为我的csv文件很大,并且最后一行比第一行更相关,所以我想阅读最后10000行。但是,即使我知道文件的长度,这也不是那么容易,因为如果我使用pandas.io.parser.read_csv("file.csv", nrows=10000, skiprows=990000)跳过1000000行csv文件的前990000行,则会跳过包含文件头的第一行,同样。 (header=0是在skiprows应用后测量的,因此它也无效。)

如何从第0行中带有标题的csv文件中获取最后10000行,最好不知道行中文件的长度?

4 个答案:

答案 0 :(得分:5)

您可以先使用以下方法计算文件大小:

size = sum(1 for l in open('file.csv'))

然后将skiprowsrange

一起使用
df = pd.read_csv('file.csv', skiprows=range(1, size - 10000))

修改

正如@ivan_pozdeev提到的解决方案,你需要通过文件两次。我尝试用pandas读取整个文件,然后使用tail方法,但这种方法比较慢。

示例数据框:

pd.DataFrame(np.random.randn(1000000,3), columns=list('abc')).to_csv('file.csv')

<强>时序

def f1():
    size = sum(1 for l in open('file.csv'))
    return pd.read_csv('file.csv', skiprows=range(1, size - 10000))

def f2():
    return pd.read_csv('file.csv').tail(10000)

In [10]: %timeit f1()
1 loop, best of 3: 1.8 s per loop

In [11]: %timeit f2()
1 loop, best of 3: 1.94 s per loop

答案 1 :(得分:3)

使用@Anton Protopopov示例文件。在单独的操作中读取文件的部分位和标题比读取整个文件要便宜得多。

直接阅读最后一行

In [22]: df = read_csv("file.csv", nrows=10000, skiprows=990001, header=None, index_col=0)

In [23]: df
Out[23]: 
               1         2         3
0                                   
990000 -0.902507 -0.274718  1.155361
990001 -0.591442 -0.318853 -0.089092
990002 -1.461444 -0.070372  0.946964
990003  0.608169 -0.076891  0.431654
990004  1.149982  0.661430  0.456155
...          ...       ...       ...
999995  0.057719  0.370591  0.081722
999996  0.157751 -1.204664  1.150288
999997 -2.174867 -0.578116  0.647010
999998 -0.668920  1.059817 -2.091019
999999 -0.263830 -1.195737 -0.571498

[10000 rows x 3 columns]

很快就这么做了

In [24]: %timeit read_csv("file.csv", nrows=10000, skiprows=990001, header=None, index_col=0)
1 loop, best of 3: 262 ms per loop

确定a-priori文件的长度非常便宜

In [25]: %timeit sum(1 for l in open('file.csv'))
10 loops, best of 3: 104 ms per loop

读入标题

In [26]: df.columns = read_csv('file.csv', header=0, nrows=1, index_col=0).columns

In [27]: df
Out[27]: 
               a         b         c
0                                   
990000 -0.902507 -0.274718  1.155361
990001 -0.591442 -0.318853 -0.089092
990002 -1.461444 -0.070372  0.946964
990003  0.608169 -0.076891  0.431654
990004  1.149982  0.661430  0.456155
...          ...       ...       ...
999995  0.057719  0.370591  0.081722
999996  0.157751 -1.204664  1.150288
999997 -2.174867 -0.578116  0.647010
999998 -0.668920  1.059817 -2.091019
999999 -0.263830 -1.195737 -0.571498

[10000 rows x 3 columns]

答案 2 :(得分:1)

完全最后N行的唯一方法是as per Anton Protopopov,首先浏览整个文件,计算行数。

但是为了下一步,可以进行优化(tail可以进行优化):

  • 当你去的时候,在长度为N的循环缓冲区中保存行的偏移量。然后在最后,缓冲区中最旧的项目将是所需的偏移量。然后根据Working with 10+GB dataset in Python Pandas,文件对象上只需f.seek()

一个更快的方法,不包括遍历整个文件将是不需要确切的行数:从我所看到的,你只需要任意大金额。所以,你可以:

  • 粗略估计您需要寻找的偏移量(例如,计算/估算一条线的平均长度)
  • 寻找那里,然后到下一个(或前一个)换行符

    如果您可以拥有嵌入换行符的数据,则需要格外小心:在这种情况下,没有万无一失的方法可以检测哪些报价正在打开以及哪些报价正在关闭。你必须假设什么可以和什么不能在内部/外部报价......甚至可以在多大程度上寻找报价以确定是否嵌入了换行符!

答案 3 :(得分:0)

您可以在pandas中尝试tail,它会返回最后n行

df.tail(10000)