首页 > 解决方案 > 基于不同列值的列的 Pandas value_counts

问题描述

我有一个数据框“学生”,如下所示:

         Cumulative.GPA  Athlete
     0   3.9             Yes
     1   3.3             Yes
     2   4.0             No
     3   3.6             Yes

我正在尝试将 GPA 的 value_counts 表分为两列:1 列用于运动员,1 列用于非运动员。输出应该是这样的(最左边的列显然继续下降到 0.0)

               Cumulative.GPA.athlete   Cumulative.GPA.nonathlete
        4.0    0                        1
        3.9    1                        0
        3.8    0                        0
        3.7    0                        0
        3.6    1                        0
        3.5    0                        0
        3.4    0                        0
        3.3    1                        0

标签: pandas

解决方案


我们可以使用crosstab来计算运动员与非运动员 GPA 的频率,然后reindex添加缺失的 GPA 增量,然后rename使rename_axis输出与预期匹配:

res = (
    pd.crosstab(df['Cumulative.GPA'], df['Athlete'])
        .reindex(index=np.arange(40, 33 - 1, -1) / 10,
                 columns=['Yes', 'No'],
                 fill_value=0)
        .rename(columns={'Yes': 'Cumulative.GPA.athlete',
                         'No': 'Cumulative.GPA.nonathlete'})
        .rename_axis(index=None, columns=None)
)

*使用int步骤来避免任何精度问题

res

     Cumulative.GPA.athlete  Cumulative.GPA.nonathlete
4.0                       0                          1
3.9                       1                          0
3.8                       0                          0
3.7                       0                          0
3.6                       1                          0
3.5                       0                          0
3.4                       0                          0
3.3                       1                          0

如果希望显示的 GPA 范围是动态的,而不是硬编码的界限,Series.max并且Series.min可以用来设置U12-Forward推荐的重新索引界限:

res = (
    pd.crosstab(df['Cumulative.GPA'], df['Athlete'])
        .reindex(index=np.arange(int(df['Cumulative.GPA'].max() * 10),
                                 int(df['Cumulative.GPA'].min() * 10) - 1,
                                 -1) / 10,
                 columns=['Yes', 'No'],
                 fill_value=0)
        .rename(columns={'Yes': 'Cumulative.GPA.athlete',
                         'No': 'Cumulative.GPA.nonathlete'})
        .rename_axis(index=None, columns=None)
)

使用的设置:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'Cumulative.GPA': [3.9, 3.3, 4.0, 3.6],
    'Athlete': ['Yes', 'Yes', 'No', 'Yes']
})

推荐阅读