如何按组计算两个列值的比率?

时间:2018-10-17 15:02:44

标签: python pandas dataframe pandas-groupby

我有一个航班列表,像这样的熊猫数据框:

airline        status          number    ...

Aer Lingus     some error A        14    ...
Aeroflot       success             47    ...
Air Canada     success              2    ...
Air Dolomiti   success              2    ...
Air Europa     some error B         4    ...
Air France     success             40    ...
Alitalia       some error A        10    ...
....

我为每次成功或错误的飞行进行一些api调用。

我想拥有的是每家航空公司的成功率。因此,我知道我可以使用groupby来统计“航空公司”和“状态”列中值的出现,但是我无法针对值的比率执行此操作。

def calculate_quote_success_ratios(flights):

    success_ratio_per_airline = flights.groupby(['airline', 'status']).count()
    # TODO: Include ratio with failures!

    return success_ratio_per_airline

预期输出应该是这样的:

airline        success_ratio

Aer Lingus     0.72
Aeroflot       0.845
Air Canada     0.935
Air Dolomiti   0.5
Air Europa     ...
....

编辑:为清楚起见,df['numbers']列不相关。因此,我只想计算每个航空公司在各种错误中“成功”所占的百分比。

4 个答案:

答案 0 :(得分:3)

明智的航班数量

count_flight=df.groupby('airline').status.count()

成功分组的分组计数

count_success=df[df['status']=='success'].groupby('airline').status.count()

pandas div返回两个先前数据帧的成组比率。

count_success.div(count_flight).fillna(0)

答案 1 :(得分:2)

我必须修改您的示例才能使其正常工作,但您只需执行df.groupby(['airline', 'status']).sum() / df.groupby(['airline']).sum()

原始df:

airline           status    number
0   Aer Lingus  some error A    14
1   Aeroflot    success 47
2   Air Canada  success 2
3   Air Dolomiti    success 2
4   Air Europa  some error B    4
5   Air France  success 40
6   Alitalia    some error A    10
7   Alitalia    success 10
8   Air France  some error B    10
9   Aer Lingus  success 12



df.groupby(['airline', 'status']).sum() / df.groupby(['airline']).sum()

                                  number
airline         status  
Aer Lingus     some error A     0.538462
               success          0.461538
Aeroflot       success          1.000000
Air Canada      success         1.000000
Air Dolomiti    success         1.000000
Air Europa    some error B      1.000000
Air France    some error B      0.200000
              success           0.800000
Alitalia      some error A      0.500000
              success           0.500000

答案 2 :(得分:1)

您可以将pd.crosstabnormalize='index'一起使用:

# data from @Chris

res = pd.crosstab(df['airline'], df['status'], values=df['number'],
                  aggfunc='count', normalize='index')

print(res[['success']])

status       success
airline             
AerLingus        0.5
Aeroflot         1.0
AirCanada        1.0
AirDolomiti      1.0
AirEuropa        0.0
AirFrance        0.5
Alitalia         0.5

答案 3 :(得分:0)

对你来说这会奏效。

我正在对正确标记的答案做一个小改动。

res = pd.crosstab(df['airline'], df['status'], values="", aggfunc='count', normalize='index')

打印(res[['成功']])