对于太大而无法放入内存的数据集,是否有一种简单的方法/模块可以在 python 中进行分组操作?
我通常会使用 pandas,但对于大型数据集它会失效。
对于太大而无法放入内存的数据集,是否有一种简单的方法/模块可以在 python 中进行分组操作?
我通常会使用 pandas,但对于大型数据集它会失效。
在评论中,@steboc 提到使用 sqlite 作为一种可能的解决方案。您可以使用任何数据库作为后端,但 sqlite 相当快并且几乎需要零设置。这是一个将一堆垃圾写入sqlite然后分组读取的示例:
首先加载一些包并设置环境:
import pandas as pd
import sqlite3
import string
## connect to a db. This db will be created if it does not exist
conn = sqlite3.connect('example.db')
c = conn.cursor()
np.random.seed(123)
## create some random data in a pandas dataframe
n = 1000000
c = 10
让我们循环 30 次,每次我们将创建一个数据框,其中包含 1 毫米的记录、10 个数字字段和一个简单的字母键。我们将在 sqlite 数据库中插入该数据框。在循环结束时,我们的数据库中将有 30 毫米的行。这在我的 MBP 上大约需要 15 分钟:
%%time
for i in arange(30):
df = pd.DataFrame(np.random.randn(n, c), columns=list(map(chr, range(65, 65+c))))
df['key'] = string.ascii_letters[i]
df.to_sql(name='test_table', if_exists='append', con=conn)
现在,如果我们要按字段中的值对所有这些数据进行分组操作,key
我们首先需要获取键的所有唯一值。一种方法是这样做:
%%time
keys_df = pd.read_sql(sql='SELECT DISTINCT key FROM test_table', con=conn)
keys_df
现在我们有了keys_df
一个数据框,其中一列包含“键”的所有唯一值。现在我们可以遍历每个组并从数据库中仅提取该组并进行分组操作。这里的例子做了一个简单的 describe():
%%time
for row in keys_df.iterrows():
tempdf = pd.read_sql(sql='SELECT * FROM test_table WHERE key=\'' + row[1][0] + '\';', con=conn)
## do anything you want with your group here.
## we'll print describe just for fun
print tempdf.describe()
print ""
显然,在现实生活中,您会将值放入数据结构中。
我希望这有助于说明如何使用 sqlite 和 pandas 来迭代数据组。
Blaze 项目很乐意通过对数据集进行分块然后在每个块上使用 Pandas 来管理大型数据集。Blaze 核心外文档可能会让您感兴趣。这是NYC Taxi 数据集上的一个明确示例。
如果您更喜欢较慢的纯 Python 解决方案,那么toolz
您可能会对这个项目感兴趣。以下是有关流分析的文档