对数据框进行排序并用百分比计算一个值

Posted

技术标签:

【中文标题】对数据框进行排序并用百分比计算一个值【英文标题】:Sort a Dataframe and count a value with percentages 【发布时间】:2018-11-13 20:06:34 【问题描述】:

我有一个这样的数据框:

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

我用它数过种类df.Kind.sort_values() 得到了这个:

1       1
2       3
3       1

现在我想以数字和百分比的形式查看第 2 类中有多少是真或假。像这样:

Art  True  False
  2     1      2
  2  0.33   0.66

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

【问题讨论】:

查看答案to this question 【参考方案1】:

交叉表 + 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

【讨论】:

【参考方案2】:

你可以简单地使用:

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

【讨论】:

【参考方案3】:

groupbysizeunstack 一起使用以通过counts 进行透视:

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

但如果想避免将integers 转换为floats 将append 更改为join 并且对于唯一列添加add_prefix

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

【讨论】:

以上是关于对数据框进行排序并用百分比计算一个值的主要内容,如果未能解决你的问题,请参考以下文章

Pandas .. 分位数函数是不是需要排序数据来计算百分位数?

计算百分位数以去除异常值的快速算法

Apache Spark:数据框中行值列表的百分比

R计算数据框中的百分比值

我如何基于一定值在jupyter中对数据进行分组?

计算不同时间段内子组的数据框中的百分比变化