2016-12-27 6 views
2

値:どのようにフィルタリングすると、グループのエントリの行によって、私は、次のデータフレーム持っ

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

を私が..グレード54と行の数をカウントしたい、1GROUPの一意の各値について。 1行目にはAAAの2回の出現がありますが、1回は数えます。

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() 

答えて

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 
0

次のようにあなたが最初に各学年のための真/偽を含む列を作成することができます。

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

Beause 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 
関連する問題