首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pandas pivot_table更快的替代品

Pandas pivot_table更快的替代品
EN

Stack Overflow用户
提问于 2019-03-28 18:31:11
回答 3查看 12.2K关注 0票数 6

我在大型数据集(1,000万行,6列)上使用Pandas pivot_table函数。由于执行时间是最重要的,我试图加快进程。目前,处理整个数据集需要花费大约8秒的时间,这是减慢速度的方法,我希望找到其他方法来提高速度/性能。

我现在的熊猫pivot_table:

代码语言:javascript
复制
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包含所有数据(10m行,从csv导入)。行业是客户的行业,月份是订单月份(1月至12月),订单是订单的数量。除订单数量( categorical数据类型)外,所有数据都转换为int数据。最初是工业,月份和client_name是字符串。

我试过使用pandas.DataFrame.unstack --这甚至更慢。我还用Dask做了实验。dask pivot_table产生了一些改进(6秒的执行时间--减少了2秒)。然而,它仍然相当缓慢。是否有更快的替代方案(用于大型数据集)?也许用groupycrosstab,.不幸的是,我根本没有其他的选择,而且我对Python和Pandas还很陌生。期待您的建议。提前感谢!

更新:

我想出这群人的方法是:

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

现在的速度要快得多,大约2-3秒。是否还有一些进一步提高速度的选择?

EN

回答 3

Stack Overflow用户

发布于 2019-03-28 19:20:46

将列、月份和行业转换为分类列:指南/分类.guide,这样可以避免大量的字符串比较。

票数 2
EN

Stack Overflow用户

发布于 2020-11-02 05:47:39

你可以使用稀疏矩阵。它们的实现速度很快,尽管有一些限制。例如:不能在矩阵上进行索引

我最近需要训练一个推荐系统(LightFM),它接受稀疏矩阵作为输入,这使我的工作变得更容易了。看到它的行动:

代码语言:javascript
复制
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))
代码语言:javascript
复制
>>> 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=...))。

票数 2
EN

Stack Overflow用户

发布于 2019-03-30 14:52:52

当您将csv文件读取到df中时,可以传递一个转换函数(通过read_csv参数converters),将client_name转换为散列,并将orders向下转换为适当的int类型,特别是无符号的orders类型。

该函数列出了类型及其范围:

代码语言:javascript
复制
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()

输出:

代码语言:javascript
复制
    int,  0:       <class 'numpy.int8'>  From:                 -128 To: 127
    int,  1:      <class 'numpy.int16'>  From:               -32768 To: 32767
    int,  2:      <class 'numpy.int32'>  From:          -2147483648 To: 2147483647
    int,  3:      <class 'numpy.int64'>  From: -9223372036854775808 To: 9223372036854775807
   uint,  0:      <class 'numpy.uint8'>  From:                    0 To: 255
   uint,  1:     <class 'numpy.uint16'>  From:                    0 To: 65535
   uint,  2:     <class 'numpy.uint32'>  From:                    0 To: 4294967295
   uint,  3:     <class 'numpy.uint64'>  From:                    0 To: 18446744073709551615
  float,  0:    <class 'numpy.float16'>
  float,  1:    <class 'numpy.float32'>
  float,  2:    <class 'numpy.float64'>
complex,  0:  <class 'numpy.complex64'>
complex,  1: <class 'numpy.complex128'>
 others,  0:             <class 'bool'>
 others,  1:           <class 'object'>
 others,  2:            <class 'bytes'>
 others,  3:              <class 'str'>
 others,  4:       <class 'numpy.void'>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55404617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档