pandas 分组 分类型 求占比

数据和结果如下,需求就是python pandas按品种分组,求属于abc类型的金额合计,按品种求金额合计,最后求出占比。

注意:如果是通过筛选数据,分组求和,在拼接求占比,那么已经实现了,现在就是想知道有没有更高级的方法,比如使用groupby.apply或者pd.pivot_table等方式实现

数据:

df = pd.DataFrame({'品种':list('AAAABBBCCD'),
                   '类型':list('abcdccdadd'),
                   '金额':[1,1,1,1,1,1,1,1,1,1]
                  })


品种类型金额
Aa1
Ab1
Ac1
Ad1
Bc1
Bc1
Bd1
Ca1
Cd1
Dd1

结果:

品种属于abc类型的金额汇总按品种汇总金额占比
A3475.00%
B2366.67%
C1250.00%
D010.00%
import pandas as pd
import pandasql as pdsql

df = pd.DataFrame({'品种':list('AAAABBBCCD'),
                   '类型':list('abcdccdadd'),
                   '金额':[1,1,1,1,1,1,1,1,1,1]
                   })

sql = """
SELECT 品种,
SUM(CASE WHEN 类型 IN ('a','b','c') 
    THEN 金额 
    ELSE 0 
    END
    ) '属于abc类型的金额汇总',
    SUM(金额) '按品种汇总金额',
    PRINTF('%2.2f%%', 
    SUM(CASE WHEN 类型 IN ('a','b','c') 
    THEN 金额 
    ELSE 0 
    END)*1.0/SUM(金额)) '占比'
FROM df 
GROUP BY 品种"""

f = lambda x: pdsql.sqldf(x, globals())
res = f(sql)
print(res)

--result
  品种  属于abc类型的金额汇总  按品种汇总金额      占比
0  A             3        4  75.00%
1  B             2        3  66.67%
2  C             1        2  50.00%
3  D             0        1   0.00%


看下下面链接对你是否有帮助
https://b23.tv/PvZ0xbo


import pandas as pd



df = pd.DataFrame({'品种':list('AAAABBBCCD'),
                   '类型':list('abcdccdadd'),
                   '金额':[1,1,1,1,1,1,1,1,1,1]
                  })


  
def fun(s):
  b = s['金额'].sum()
  t=0
  for key,value in s['类型'].items():
    if ((value == 'a') | (value == 'b') | (value == 'c')):
      t = s['金额'][key] + t    
  return  pd.DataFrame([(t , b , t/b)],columns=['属于abc类型的金额汇总','按品种汇总金额','占比'])


ss = df.groupby(['品种']).apply(fun)



print(ss)

      属于abc类型的金额汇总  按品种汇总金额        占比
品种
A  0             3        4  0.750000
B  0             2        3  0.666667
C  0             1        2  0.500000
D  0             0        1  0.000000

我自己写了一个,结果对了,但是为什么会有一列0呢?????

您好,使用groupby().apply(),功能已实现。如有帮助还请采纳。

import pandas as pd

df = pd.DataFrame({'品种':list('AAAABBBCCD'),
                   '类型':list('abcdccdadd'),
                   '金额':[1,1,1,1,1,1,1,1,1,1]
                  })

# 1.属于abc类型的金额汇总
s1 = df.groupby("品种").apply(lambda x: x[x['类型'] != 'd']['金额'].sum())
# 2.按品种汇总金额
s2 = df.groupby("品种").apply(lambda x: x['金额'].sum())

df2 = pd.DataFrame({"属于abc类型的金额汇总": s1,
                    "按品种汇总金额": s2})

# 3.求占比
df2["占比"] = df2.apply(lambda x: x["属于abc类型的金额汇总"]/x["按品种汇总金额"], axis=1)

# 输出结果
print(df2)

输出结果如下图所示:

img