Сортируйте Dataframe и посчитайте значение в процентах - PullRequest
0 голосов
/ 04 июня 2018

У меня есть DataFrame, подобный этому:

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

Я посчитал все виды с ним df.Kind.sort_values() и получил это:

1       1
2       3
3       1

Теперь я хочу увидеть, сколько Kind2 являются истинными или ложными как число и процент.Вот так:

Art  True  False
  2     1      2
  2  0.33   0.66

Может кто-нибудь мне помочь?С наилучшими пожеланиями

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

кросс-таблица + 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
0 голосов
/ 04 июня 2018

Вы можете просто использовать:

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
0 голосов
/ 04 июня 2018

Используйте groupby с size и unstack для разворота на count s:

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 s в float s, измените 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...