熊猫:df.groupby()对大数据集来说太慢了。任何替代方法?

时间:2017-06-22 16:05:55

标签: python pandas grouping bigdata

df = df.groupby(df.index).sum()

我有一个包含380万行(单列)的数据帧,我正在尝试按索引对它们进行分组。但是完成计算需要花费很长时间。有没有其他方法来处理非常大的数据集?在此先感谢!!!!

我正在用Python写作。

数据如下所示。 索引是客户ID。我想将qty_liter分组为Index

df = df.groupby(df.index).sum()

但是这行代码耗费了太多时间......

enter image description here

有关此df的信息如下:

df.info()

<class 'pandas.core.frame.DataFrame'> Index: 3842595 entries, -2147153165 to \N Data columns (total 1 columns): qty_liter object dtypes: object(1) memory usage: 58.6+ MB

3 个答案:

答案 0 :(得分:1)

问题是您的数据不是数字。处理字符串比处理数字需要更长的时间。先试试这个:

df.index = df.index.astype(int)
df.qty_liter = df.qty_liter.astype(float)

然后再次groupby()。它应该快得多。如果是,请查看是否可以修改数据加载步骤以从头开始使用正确的dtypes。

答案 1 :(得分:1)

您的数据分类太多,这是导致 groupby 代码太慢的主要原因。我尝试使用 Bodo 来查看它如何处理大型数据集上的 groupby。我使用常规顺序 Pandas 和并行化 Bodo 运行代码。 Pandas 用了大约 20 秒,Bodo 只用了 5 秒。 Bodo 基本上会自动并行化您的 Pandas 代码,并允许您在多个处理器上运行它,这是原生 Pandas 无法做到的。最多可免费使用四个内核:https://docs.bodo.ai/latest/source/install.html

数据生成注意事项:我生成了一个相对较大的数据集,有 2000 万行和 18 个数值列。为了使生成的数据与您的数据集更相似,添加了另外两个名为“index”和“qty_liter”的列。

#data generation

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(20000000, 18), columns = list('ABCDEFGHIJKLMNOPQR'))
df['index'] = np.random.randint(2147400000,2147500000,20000000).astype(str)
df['qty_liter'] = np.random.randn(20000000)

df.to_parquet("data.pq")

使用普通熊猫:

import time
import pandas as pd
import numpy as np

start = time.time()
df = pd.read_parquet("data.pq")
grouped = df.groupby(['index'])['qty_liter'].sum()
end = time.time()
print("computation time: ", end - start)
print(grouped.head())

output:
computation time:  19.29292106628418
index
2147400000    29.701094
2147400001    -7.164031
2147400002   -21.104117
2147400003     7.315127
2147400004   -12.661605
Name: qty_liter, dtype: float64

与博多:

%%px

import numpy as np
import pandas as pd
import time
import bodo

@bodo.jit(distributed = ['df'])
def group_by():
    start = time.time()
    df = pd.read_parquet("data.pq")
    df = df.groupby(['index'])['qty_liter'].sum()
    end = time.time()
    print("computation time: ", end - start)
    print(df.head())
    return df
    
df = group_by()

output:
[stdout:0] 
computation time:  5.12944599299226
index
2147437531     6.975570
2147456463     1.729212
2147447371    26.358158
2147407055    -6.885663
2147454784    -5.721883
Name: qty_liter, dtype: float64

免责声明:我是在 Bodo.ai 工作的数据科学家倡导者

答案 2 :(得分:0)

我不使用字符串,而是使用定义组的整数值。它仍然很慢:大约 3 分钟,而在 Stata 中只有几分之一秒。观测数约为113k,x、y、z定义的组数约为26k。

a= df.groupby(["x", "y", "z"])["b"].describe()[['max']]

x,y,z:整数值

b:实际价值