熊猫的更快替代品pivot_table

时间:2019-03-28 18:31:11

标签: python pandas performance numpy dask

我在大型数据集(1000万行,6列)上使用Pandas pivot_table函数。由于执行时间至关重要,因此我尝试加快执行速度。目前处理整个数据集大约需要8秒钟,这很慢,我希望找到其他方法来提高速度/性能。

我当前的熊猫数据透视表:

df_pivot = df_original.pivot_table(index="industry", columns = "months",
                    values = ["orders", "client_name"],
                    aggfunc ={"orders": np.sum, "client_name": pd.Series.nunique})

df_original包含所有数据(从CSV导入的10m行)。行业是客户的行业,月份是订单月份(一月到十二月),订单是订单数量。除订单数(categorical数据类型)外,所有数据均转换为int数据。最初是行业,月份和client_name是字符串。

我尝试使用pandas.DataFrame.unstack-甚至更慢。我还尝试了Daskdask pivot_table产生了一些改进(执行时间为6秒-减少了2秒)。但是,它仍然很慢。 是否有更快的替代方法(适用于大型数据集)?也许用groupycrosstab重新创建了数据透视表,...不幸的是,我根本没有其他替代方法可以工作,而且我对Python和Pandas还是很陌生... 期待您的建议。预先感谢!

更新

我用以下方法弄清了分组方式:

df_new = df_original.groupby(["months", "industry"]).agg({"orders": np.sum, "client_name": pd.Series.nunique}).unstack(level="months").fillna(0)

现在快了大约2-3秒。还有一些选择可以进一步提高速度吗?

3 个答案:

答案 0 :(得分:1)

将月份和行业列转换为分类列: https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html 这样可以避免很多字符串比较。

答案 1 :(得分:0)

当您将csv文件读入df时,可以传递转换函数(通过read_csv参数converters),将client_name转换为哈希并向下转换{{1 }}转换为适当的orders类型,尤其是无符号类型。

此功能列出了类型及其范围:

int

输出:

import numpy as np

def list_np_types():
    for k, v in np.sctypes.items():
        for i, d in enumerate(v):
            if np.dtype(d).kind in 'iu':
                # only int and uint have a definite range
                fmt = '{:>7}, {:>2}: {:>26}  From: {:>20}\tTo: {}'
                print(fmt.format(k, i, str(d),
                                 str(np.iinfo(d).min),
                                 str(np.iinfo(d).max)))

            else:
                print('{:>7}, {:>2}: {:>26}'.format(k, i, str(d)))


list_np_types()

答案 2 :(得分:0)

您可以使用稀疏矩阵。它们实施起来很快,但是有一些限制。例如:您无法在COO_matrix

上建立索引

我最近需要训练一个推荐器系统(lightFM),它接受了稀疏矩阵作为输入,这使我的工作变得容易得多。实际观看:

row  = np.array([0, 3, 1, 0])
col = np.array([0, 3, 1, 2])
data = np.array([4, 5, 7, 9])
mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4))
>>> print(mat)
  (0, 0)    4
  (3, 3)    5
  (1, 1)    7
  (0, 2)    9
>>> print(mat.toarray())
[[4 0 9 0]
 [0 7 0 0]
 [0 0 0 0]
 [0 0 0 5]]

如您所见,它将使用您拥有的数据的列和行自动为您创建数据透视表,并用零填充其余部分。您也可以将稀疏矩阵转换为数组和数据帧(df = pd.DataFrame.sparse.from_spmatrix(mat, index=..., columns=...)