简体   繁体   中英

How can I group by a column then calculate a percentage of a column

I am having some trouble with a groupby then trying to calculate the times used by the cashier and the creditcard.

DF

Date          Cashier          Creditcard_number
2017-01-01    Steve Rogers     1111-1111-1111-1111
2017-01-03    Steve Green      1111-1111-1121-1111
2017-01-04    Steve Green      1111-2211-1111-1111
2017-01-02    Steve Rogers     1111-1111-1111-1111

Goal

Creditcard_number         Cashier             Times_Used_By_cashier
1111-1111-1111-1111       Steve Rogers        1/2
1111-1111-1121-1111       Steve Green         1/1
1111-2211-1111-1111       Steve Green         1/1

Edit

DF

Date          Cashier          Creditcard_number
2017-01-01    Steve Rogers     1111-1111-1111-1111
2017-01-02    Steve Green      1111-1111-1111-1111
2017-01-03    Steve Green      1111-1111-1121-1111
2017-01-04    Steve Green      1111-2211-1111-1111
2017-01-02    Steve Rogers     1111-1111-1111-1111

Goal

Creditcard_number         Cashier             Times_Used_By_cashier
1111-1111-1111-1111       Steve Rogers        2/3
1111-1111-1121-1111       Steve Green         1/1
1111-2211-1111-1111       Steve Green         1/1

You can perform two groupby + count operations, followed by an index-aligned division:

i = df.groupby(['Creditcard_number']).Cashier.count()
j = df.groupby(['Cashier', 'Creditcard_number']).Cashier.count()

(j / i).reset_index(name='Times_Used_By_Cashier')

        Cashier    Creditcard_number  Times_Used_By_Cashier
0   Steve Green  1111-1111-1111-1111                    0.5
1   Steve Green  1111-1111-1121-1111                    1.0
2   Steve Green  1111-2211-1111-1111                    1.0
3  Steve Rogers  1111-1111-1111-1111                    0.5

Or, if you want the result in "x/y" form (as strings), then -

(j.astype(str) + '/' + i.astype(str)).reset_index(name='Times_used_by_cashier')

        Cashier    Creditcard_number Times_used_by_cashier
0   Steve Green  1111-1111-1111-1111                   1/2
1   Steve Green  1111-1111-1121-1111                   1/1
2   Steve Green  1111-2211-1111-1111                   1/1
3  Steve Rogers  1111-1111-1111-1111                   1/2

Try to match your output list above..

df.groupby('Creditcard_number').agg({'Cashier':'first','Creditcard_number':lambda x : x.nunique()/len(x)})
Out[20]: 
                         Cashier  Creditcard_number
Creditcard_number                                  
1111-1111-1111-1111  SteveRogers                0.5
1111-1111-1121-1111   SteveGreen                1.0
1111-2211-1111-1111   SteveGreen                1.0

Or

s=df.groupby('Creditcard_number').agg({'Cashier':['first','nunique']})
s.columns=s.columns.droplevel(0)

s.assign(nunique='1/'+s['nunique'].astype(str))
Out[28]: 
                           first nunique
Creditcard_number                       
1111-1111-1111-1111  SteveRogers     1/2
1111-1111-1121-1111   SteveGreen     1/1
1111-2211-1111-1111   SteveGreen     1/1

您可以执行df.groupby(Credit_Card).count()然后从那里进行任何操作

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM