在熊猫中读取大型csv的最后N行

时间:2019-03-26 08:42:06

标签: python pandas

我的文件包含50 GB的数据。我知道如何使用Pandas进行数据分析。
我只需要1000条大行或行,就需要完整的50 GB。
因此,我想到了在entry_points={ 'console_scripts': [ 'hello=<package>.test:main', ], }, 中使用nrows选项。
我已经编写了如下代码:

read_csv()

但是它排在前1000行。我需要最后100行。因此,我这样做并收到错误:

import pandas as pd
df = pd.read_csv("Analysis_of_50GB.csv",encoding="utf-16",nrows=1000,index_col=0)

我什至尝试在df = pd.read_csv("Analysis_of_50GB.csv",encoding="utf-16",nrows=-1000,index_col=0) ValueError: 'nrows' must be an integer >=0 中使用chunksize。但是它仍然加载完整的文件。甚至输出不是read_csv(),而是DataFrame

因此,请让我知道在这种情况下可以做什么。

请注意,我不想打开完整文件...

4 个答案:

答案 0 :(得分:2)

一种纯熊猫方法:

import pandas as pd
line = 0
chksz = 1000
for chunk in pd.read_csv("Analysis_of_50GB.csv",encoding="utf-16",chunksize = chksz,index_col=0, usecols=0):
    line += chunk.shape[0]

因此,这只是计算行数,出于性能原因,我们仅读取第一列。

一旦我们有了总行数,我们就从中减去最后要的行数:

df = pd.read_csv("Analysis_of_50GB.csv",encoding="utf-16", skiprows = line - 1000,index_col=0)

答案 1 :(得分:1)

我认为您需要同时使用行距和行距。假设您的文件有1000行,

df =pd.read_csv('"Analysis_of_50GB.csv", encoding="utf16",skiprows = lambda x: 0<x<=900, nrows=1000-900,index_col=0)

读取从901到1000的所有行。

答案 2 :(得分:1)

您应该考虑使用dask,它可以在后台进行分块并允许您处理非常大的数据帧。它的工作流程与熊猫非常相似,并且最重要的功能已经实现。

答案 3 :(得分:1)

通常的方法是读取整个文件,并按照接受的Efficiently Read last 'n' rows of CSV into DataFrame的建议在出队中保留1000行。但是对于50GB的巨大文件来说,它可能不是最佳选择。

在这种情况下,我将尝试进行简单的预处理:

  • 打开文件
  • 读取和丢弃1000行
  • 使用ftell可以大致了解到目前为止所读的内容
  • 从文件末尾查找该大小,然后在较大的缓冲区(如果有足够的内存)中读取文件末尾
  • 将'\ n'字符在缓冲区中的位置以大小为1001的出队存储(文件可能具有终端'\ n'),我们称之为deq
  • 确保您有1001个换行符,否则以较大的偏移量进行迭代
  • 使用缓冲区中包含的1000行加载数据帧:

    df = pd.read_csv(io.StringIO(buffer[d[0]+1:]))
    

代码可能是(提防:未经测试):

with open("Analysis_of_50GB.csv", "r", encoding="utf-16") as fd:
    for i in itertools.islice(fd, 1250):      # read a bit more...
        pass
    offset = fd.tell()
    while(True):
        fd.seek(-offset, os.SEEK_END)
        deq = collection.deque(maxlen = 1001)
        buffer = fd.read()
        for i,c in enumerate(buffer):
            if c == '\n':
                deq.append(i)
        if len(deq) == 1001:
            break
        offset = offset * 1250 // len(deq)

df = pd.read_csv(io.StringIO(buffer[d[0]+1:]))