简体   繁体   中英

Python: For each unique ID, find its code and its value and calculate the ratio

Actual dataframe consist of more than a million rows.

Say for example a dataframe is:

UniqueID  Code  Value  OtherData      
1         A     5      Z01 
1         B     6      Z02
1         C     7      Z03
2         A     10     Z11
2         B     11     Z24
2         C     12     Z23 
3         A     10     Z21
4         B     8      Z10

I want to obtain ratio of A/B for each UniqueID and put it in a new dataframe. For example, for UniqueID 1, its ratio of A/B = 5/6.

What is the most efficient way to do this in Python?

Want:

UniqueID  RatioAB        
1         5/6
2         10/11
3         Inf
4         0

Thank you.

One approach is using pivot_table , aggregating with the sum in the case there are multiple occurrences of the same letters (otherwise a simple pivot will do), and evaluating on columns A and B :

df.pivot_table(index='UniqueID', columns='Code', values='Value', aggfunc='sum').eval('A/B')

    UniqueID
1    0.833333
2    0.909091
3         NaN
4         NaN
dtype: float64

If there is maximum one occurrence of each letter per group:

df.pivot(index='UniqueID', columns='Code', values='Value').eval('A/B')

    UniqueID
1    0.833333
2    0.909091
3         NaN
4         NaN
dtype: float64

If you only care about A/B ratio:

df1 = df[df['Code'].isin(['A','B'])][['UniqueID', 'Code', 'Value']]
df1 = df1.pivot(index='UniqueID',
                columns='Code', 
                values='Value')

df1['RatioAB'] = df1['A']/df1['B']

最明显的方式是通过 groupby。

df.groupby('UniqueID').apply(lambda g: g.query("Code == 'A'")['Value'].iloc[0] / g.query("Code == 'B'")['Value'].iloc[0]) 

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