对数据帧进行排序并使用百分比计算值

时间:2018-06-04 13:08:23

标签: python python-3.x pandas dataframe

我有一个像这样的DataFrame:

Kind   Status
1      True
2      False
3      True
2      False
2      True

我用它来计算种类df.Kind.sort_values() 得到了这个:

1       1
2       3
3       1

现在我想看看Kind 2中有多少是真或假的数字和百分比。像这样:

Art  True  False
  2     1      2
  2  0.33   0.66

有人能帮助我吗? 最好的问候

3 个答案:

答案 0 :(得分:7)

交叉表+ div

使用pandas.crosstab

res = pd.crosstab(df['Kind'], df['Status'])

res[['Pct False', 'Pct True']] = res.div(res.sum(axis=1), axis=0)

print(res)

Status  False  True  Pct False   Pct True
Kind                                     
1           0     1   0.000000   1.000000
2           2     1   0.666667   0.333333
3           0     1   0.000000   1.000000

在我看来,这是显示数据的最自然方式。不建议将计数与单个系列中的百分比相结合。

交叉表+交叉表规范化

或者,您可以加入几个crosstab个结果,一个标准化,另一个不标记。

res = pd.crosstab(df['Kind'], df['Status'])\
        .join(pd.crosstab(df['Kind'], df['Status'], normalize='index'), rsuffix='_pct')

print(res)

Status  False  True  False_pct  True_pct
Kind                                    
1           0     1   0.000000  1.000000
2           2     1   0.666667  0.333333
3           0     1   0.000000  1.000000

交叉表仅标准化

如果您只查看百分比,可以使用normalize参数:

res = pd.crosstab(df['Kind'], df['Status'], normalize='index')

print(res)

Status     False     True 
Kind                      
1       0.000000  1.000000
2       0.666667  0.333333
3       0.000000  1.000000

答案 1 :(得分:3)

groupbysize unstack使用add_prefix进行count的转移:

df1 = df.groupby(['Kind','Status']).size().unstack(fill_value=0)
#alternative solution, slowier in large data
#df1 = pd.crosstab(df['Kind'], df['Status'])
print (df1)
Status  False  True 
Kind                
1           0      1
2           2      1
3           0      1

然后除以sum并附加到原始文件:

df = df1.append(df1.div(df1.sum(axis=1), axis=0)).sort_index()
print (df)
Status     False     True 
Kind                      
1       0.000000  1.000000
1       0.000000  1.000000
2       2.000000  1.000000
2       0.666667  0.333333
3       0.000000  1.000000
3       0.000000  1.000000
print (df.loc[2])
Status     False     True 
Kind                      
2       2.000000  1.000000
2       0.666667  0.333333

但是,如果要避免将integer转换为float,请将append更改为join,对于唯一列,请添加fee_talbe -- date and price on a daily basis

df = df1.join(df1.div(df1.sum(axis=1), axis=0).add_prefix('pct '))
print (df)
Status  False  True  pct False  pct True
Kind                                    
1           0     1   0.000000  1.000000
2           2     1   0.666667  0.333333
3           0     1   0.000000  1.000000

print (df.loc[[2]])

Status  False  True  pct False  pct True
Kind                                    
2           2     1   0.666667  0.333333

答案 2 :(得分:0)

您可以简单地使用:

g = df.loc[df['Kind']==2].groupby(['Kind', 'Status']).size().unstack()
pd.concat([g,g.apply(lambda x: round(x / (x[False]+x[True]), 2), axis=1)])

输出:

Status  False   True
Kind        
2   2.00    1.00
2   0.67    0.33