如何按行值过滤和分组条目

时间:2016-12-27 19:44:50

标签: python pandas

我有以下数据框:

df = 
ID   GROUP_1  GROUP_2  GROUP_3  GRADE
1A   AAA      BBB      AAA      5
1B   BBB      BBB      CCC      4
1C   AAA      BBB      BBB      4

我想为5的每个唯一值计算成绩41,...,GROUP的行数。请注意,在第1行中,有AAA出现了2次,但我算了一次。

给定数据集的预期输出如下:

GROUP  GRADE_1   GRADE_2   GRADE_3   GRADE_4   GRADE_5
AAA    0         0         0         1         1
BBB    0         0         0         2         1
CCC    0         0         0         1         0

我有以下给定的代码,它工作正常,不包括分组(groupby('GRADE'))。我不知道如何按GRADE对结果进行分组,并创建列GRADE_1GRADE_2,...,GRADE_5

df.groupby('GRADE').filter(regex="^GROUP").stack().reset_index(level=1, drop=True).reset_index().drop_duplicates()[0].value_counts()

3 个答案:

答案 0 :(得分:2)

试试这个:

In [56]: df
Out[56]:
   ID GROUP_1 GROUP_2 GROUP_3  GRADE
0  1A     AAA     BBB     AAA      5
1  1B     BBB     BBB     CCC      4
2  1C     AAA     BBB     BBB      4

In [57]: (df.set_index('GRADE')
    ...:    .filter(like='GROUP_')
    ...:    .stack()
    ...:    .to_frame('GROUP')
    ...:    .reset_index()
    ...:    .pivot_table(index='GROUP', columns='GRADE', aggfunc='size', fill_value=0)
    ...: )
    ...:
Out[57]:
GRADE  4  5
GROUP
AAA    1  2
BBB    4  1
CCC    1  0

答案 1 :(得分:1)

因为MaxU的答案太好了。我必须加倍努力才能做出有用的贡献。如果不太直观,这个解决方案意味着快速(呃)。

groups_df = df.filter(like='GROUP')
groups = groups_df.values.ravel().tolist()
grades = df.GRADE.values.repeat(len(groups_df.columns)).tolist()
s = pd.value_counts(list(zip(groups, grades)))
s.index = pd.MultiIndex.from_tuples(
    s.index.values.tolist(), names=['Group', 'GRADE'])

s.unstack(fill_value=0)

GRADE  4  5
Group      
AAA    1  2
BBB    4  1
CCC    1  0

答案 2 :(得分:0)

您可以先为每个成绩创建包含True / False的列,如下所示:

for grade in df.GRADE.unique():
    col = 'GRADE_{}'.format(grade)
    df[col] = df.GRADE.apply(lambda x: x == grade)