对于太大而无法放入内存的数据集,是否有一种简单的方法/模块可以在 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 次,每次我们都会创建一个包含 1mm 记录、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 迭代数据组。
关于python - 大型数据集的分组操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27559757/