python - 使用大型csv的pandas结构(迭代和chunksize)

Tho*_*s P 22 python csv bigdata dataframe pandas

我有一个大的csv文件,大约600mb,有1100万行,我想创建像枢轴,直方图,图形等统计数据.显然,我只是想正常阅读它:

df = pd.read_csv('Check400_900.csv', sep='\t')
Run Code Online (Sandbox Code Playgroud)

不起作用,所以我发现迭代和chunksize在类似的帖子,所以我用

df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
Run Code Online (Sandbox Code Playgroud)

一切都很好,我可以举例print df.get_chunk(5) 来说,只搜索整个文件

for chunk in df:
    print chunk
Run Code Online (Sandbox Code Playgroud)

我的问题是我不知道如何在整个df中使用下面这些东西,而不仅仅是一个块

plt.plot()
print df.head()
print df.describe()
print df.dtypes
customer_group3 = df.groupby('UserID')
y3 = customer_group.size()
Run Code Online (Sandbox Code Playgroud)

我希望我的问题不那么令人困惑

jez*_*ael 23

解决方案,如果需要创建一个大的,DataFrame如果需要一次处理所有数据(可能的,但不推荐):

然后使用concat为df的所有块,因为函数的输出类型:

df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
Run Code Online (Sandbox Code Playgroud)

不是数据帧,而是pandas.io.parsers.TextFileReader- .

tp = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
print tp
#<pandas.io.parsers.TextFileReader object at 0x00000000150E0048>
df = pd.concat(tp, ignore_index=True)
Run Code Online (Sandbox Code Playgroud)

我认为有必要为函数添加参数ignore indexconcat,因为避免了索引的重复性.

编辑:

但是如果想要使用聚合这样的大数据,那就更好用了dask,因为它提供了高级并行性.

  • 这是一个可怕的想法,正是因为@hellpanderr在第一条评论中提出的原因.这与仅使用`chunksize`调用`read_csv`具有相同的效果,除了它需要两倍的内存(因为你现在不仅需要保存巨大的DataFrame,而且还需要保存所有添加到该DataFrame的块)同一时间).这不可能解决OP的问题,只会使情况变得更糟. (3认同)
  • 他可以做`tp.read()`来获取一个数据帧,但它可能不适合他的记忆,所以他问你是否可以在没有完全加载的情况下工作. (2认同)

aba*_*ert 8

没有需要concat在这里.这就像写作sum(map(list, grouper(tup, 1000)))而不是写作list(tup).唯一iteratorchunksize=1000所做的是给你的迭代而不是读取整个事情1000行DataFrames读者对象.如果你想要一次完整的东西,就不要使用那些参数.

但是如果一次将整个文件读入内存太昂贵(例如,你需要花费大量内存MemoryError,或者通过将它放入交换地狱来减慢你的系统爬行速度),这正是chunksize为了什么.

问题是您命名了生成的迭代器df,然后尝试将其用作DataFrame.它不是DataFrame; 它是一个迭代器,可以逐个为您提供1000行的DataFrame.

当你这样说:

我的问题是我不知道如何在整个df中使用下面这些东西,而不仅仅是一个块

答案是,你做不到.如果您无法将整个内容加载到一个巨型DataFrame中,则无法使用一个巨型DataFrame.你必须围绕块重写代码.

而不是这个:

df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
print df.dtypes
customer_group3 = df.groupby('UserID')
Run Code Online (Sandbox Code Playgroud)

......你必须做这样的事情:

for df in pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000):
    print df.dtypes
    customer_group3 = df.groupby('UserID')
Run Code Online (Sandbox Code Playgroud)

通常,您需要做的是聚合一些数据 - 将每个块减少到只有您需要的部分更小的东西.例如,如果要按组对整个文件groupby求和,则可以使用每个块,然后按组对块进行求和,并为每个组存储运行总计的序列/数组/列表/字典.

当然,它比仅仅一次总结一个巨大的系列稍微复杂一点,但是没有办法解决这个问题.(除购买更多的RAM和/或切换到64位.)这是怎么iteratorchunksize解决的问题:通过允许您当你需要做出这种权衡.


小智 5

您需要连接夹头。例如:

df2 = pd.concat([chunk for chunk in df])
Run Code Online (Sandbox Code Playgroud)

然后运行你的命令 df2

  • 感谢您的回复,但我再次收到“MemoryError” (3认同)