获取 csv 文件的最后 10000 行



在熊猫中,我可以使用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 行,最好不知道文件的行长?

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

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

然后将skiprowsrange一起使用:

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

编辑

正如@ivan_pozdeev提到的,您需要通过该文件进行两次。我尝试用熊猫读取整个文件,然后使用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

使用@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

先验地确定文件的长度非常便宜

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]
准确

获取最后 N 行的唯一方法是按照安东·普罗托波波夫(Anton Protopopov)的说法,首先浏览整个文件,计算行数。

但是对于下一步,采取它们,可以进行优化(tail这样做):

  • 在此过程中,将行的偏移量保存在长度为 N 的圆形缓冲区中。然后在最后,缓冲区中最早的项目将是所需的偏移量。然后,只需按照在Python Pandas中使用10 + GB数据集对文件对象进行f.seek()

一种不包括遍历整个文件的更快方法是不需要确切的行数:据我所知,您只需要任意大量的行。因此,您可以:

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

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

你可以尝试从熊猫的尾巴,它返回最后n行

df.tail(10000)

最新更新