5

对于太大而无法放入内存的数据集,是否有一种简单的方法/模块可以在 python 中进行分组操作?

我通常会使用 pandas,但对于大型数据集它会失效。

4

2 回答 2

5

在评论中,@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 来迭代数据组。

于 2014-12-19T18:43:18.093 回答
3

Blaze 项目很乐意通过对数据集进行分块然后在每个块上使用 Pandas 来管理大型数据集。Blaze 核心外文档可能会让您感兴趣。这是NYC Taxi 数据集上的一个明确示例。

如果您更喜欢较慢的纯 Python 解决方案,那么toolz您可能会对这个项目感兴趣。以下是有关流分析的文档

于 2014-12-20T01:59:15.460 回答