如何在python中对两列进行透视和排序?

问题描述 投票:1回答:2

我有一个超大的客户数据框,项目类别和价格。我想做一些初步调查:

  • 根据他们的总支出来识别最重要的n = 5个客户。
  • 对于每个客户,确定他们花费的顶级类别。
  • 然后可能按照降序显示一个情节,显示最高客户的名字为X,他们的消费为Y.每个人如何显示他们的购物类别?

这需要转动和排序。这是一个样本数据生成器,感谢here

import numpy as np
import pandas as pd
from numpy.core.defchararray import add

np.random.seed(42)
n = 20

cols = np.array(['cust', 'cat'])
arr1 = (np.random.randint(5, size=(n, 2)) // [2, 1]).astype(str)
df = pd.DataFrame(
    add(cols, arr1), columns=cols
).join(
    pd.DataFrame(np.random.rand(n, 1).round(2)).add_prefix('val')
)
print(df)

df.pivot_table(index=['cust'],values=['val0'],aggfunc=[np.sum])

df.pivot_table(index=['cust','cat'],values=['val0'],aggfunc=[np.size,np.sum])

# the order according the previous line should be cust1,cust0,cust2. How to do? The following is the desired output in this case.

                size sum
                val0 val0
cust    cat
cust1   cat4    6.0  4.27
        cat3    2.0  1.07
        cat2    2.0  0.98
        cat0    2.0  0.44
        cat1    2.0  0.43

cust0   cat1    1.0  0.94
        cat4    1.0  0.91
        cat2    1.0  0.66
        cat3    1.0  0.03

cust2   cat1    2.0  1.25

非常感谢你!

python pandas pivot pivot-table pandas-groupby
2个回答
1
投票

这里有更好的聚合sum,以避免列中的MultiIndex

第一次聚合sum

s = df.groupby('cust')['val0'].sum()
print (s)
cust
cust0    2.54
cust1    7.19
cust2    1.25
Name: val0, dtype: float64

然后通过Series.nlargest得到最高值:

top5 = s.nlargest(5)
print (top5)
cust
cust1    7.19
cust0    2.54
cust2    1.25
Name: val0, dtype: float64

如有必要,可以通过boolean indexingisin过滤top5值:

df1 = df[df['cust'].isin(top5.index)].copy()
#print(df1)

为了正确排序cust创建有序分类并通过两个过滤列聚合,最后排序第一级cust和列size

df1['cust'] = pd.Categorical(df1['cust'], ordered=True, categories=top5.index)
df2 = (df1.groupby(['cust','cat'])['val0'].agg([np.size,np.sum])
         .sort_values(['cust','size'], ascending=[True, False])
         .reset_index())
print (df2)
    cust   cat  size   sum
0  cust1  cat4   6.0  4.27
1  cust1  cat0   2.0  0.44
2  cust1  cat1   2.0  0.43
3  cust1  cat2   2.0  0.98
4  cust1  cat3   2.0  1.07
5  cust0  cat1   1.0  0.94
6  cust0  cat2   1.0  0.66
7  cust0  cat3   1.0  0.03
8  cust0  cat4   1.0  0.91
9  cust2  cat1   2.0  1.25

DataFrame.plot.bar的最后一个支点和情节:

df2.pivot('cust','cat','size').plot.bar()

0
投票

不确定我是否理解您想要的确切概述,但这也可以通过使用groupby然后使用agg方法,如下所示:

overview = df.groupby('cust').agg({'val0':'sum',
                                   'cat':'max'}).reset_index().sort_values('val0', ascending=False)

    cust    val0    cat
1   cust1   7.19    cat4
0   cust0   2.54    cat4
2   cust2   1.25    cat1

因此,这会聚合在客户层面并汇总其总支出,并显示他们花费最多的类别。

您不必使用reset_index()函数,在这种情况下,它会产生以下结果:

overview = df.groupby('cust').agg({'val0':'sum',
                                   'cat':'max'}).sort_values('val0', ascending=False)


        val0    cat
cust        
cust1   7.19    cat4
cust0   2.54    cat4
cust2   1.25    cat1

最后,如果您想要前5位客户,您可以简单地使用.head(5),因为值已经按降序排序:

overview = df.groupby('cust').agg({'val0':'sum',
                                   'cat':'max'}).sort_values('val0', ascending=False).head(5)
© www.soinside.com 2019 - 2024. All rights reserved.