简体   繁体   中英

Use pandas groupby function on multiple columns

I have a DataFrame similar to this:

Key    Departure    Species1   Species2   Status
1         R          Carlan     Carlan      D
1         R          Scival     Carex       C
2         R          Carlan     Scival      D
2         R          Scival     Bougra      C  
3         D          Carlan     Carlan      D
3         D          Scival     Scival      C

I want to count the occurrences of each unique Species1 for a given Departure and Status of D of C

My desired output is:

Species1   RD    RC    DD    DC
Carlan     2     NaN   1     NaN
Scival     NaN   2     NaN   1

Make a new column that is the combination of Departure and Status

df['comb'] = df.Departure + df.Status
df
#  Key Departure Species1 Species2 Status comb
#0   1         R   Carlan   Carlan      D   RD
#1   1         R   Scival    Carex      C   RC
#2   2         R   Carlan   Scival      D   RD
#3   2         R   Scival   Bougra      C   RC
#4   3         D   Carlan   Carlan      D   DD
#5   3         D   Scival   Scival      C   DC

Then you can groupby:

gb    = df.groupby(['Species1', 'comb'])
gb.groups
#{('Carlan', 'DD'): [4],
#('Carlan', 'RD'): [0, 2],
#('Scival', 'DC'): [5],
#('Scival', 'RC'): [1, 3]}

Now organize the results into a list, where each element is a tuple (column, Series(data, index)) representing a single data point in a new dataframe

items = [ (key[1], pandas.Series( [len(val)], index=[key[0]] ) )for key,val in gb.groups.items() ]

And make a new dataframe from the items:

result = pandas.from_items( items)
result
#        RC  DC  DD  RD
#Carlan NaN NaN   1   2
#Scival   2   1 NaN NaN

Extra info

See this link for ideas on crating new dataframes from various objects. When you want to create a dataframe from individual data points (eg (Species1,comb) ), then from_items is your best option.

Use the pandas.crosstab() method. A single line of code:

pd.crosstab(df.Species1, [df.Departure, df.Status])

The resulting table:

在此处输入图片说明

If you combine with @dermen's 'comb' column,

df['comb'] = df.Departure + df.Status
pd.crosstab(df.Species1, df.comb)

you'll get:

在此处输入图片说明

If you really want those 'NaN', just tack on a .replace('0', np.nan) , like so (assuming an import numpy as np has already been done):

pd.crosstab(df.Species1, df.comb).replace('0', np.nan)

在此处输入图片说明

您可以对多个列使用groupby查询,并使用.agg函数来计算出现次数:

df.groupby(['Species1', 'Departure', 'Status']).agg(['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