2017-01-05 4 views
4

評価を1回、2〜3回、3回以上行ったグループの中で、どれくらい多くの人がGRADE 1,2,3,4,5を出したか知りたい。例えば、1回の評価を行う人々のグループには、IDが2および4の人が含まれています。このグループには、完全に1つの評価5と1つの評価1があります。頻度で行をグループ化する方法は?

df = 

ID_PERSON EVALUATION_GRADE 
1   2 
1   2 
1   3 
1   5 
2   5 
3   2 
3   5 
3   1 
4   1 
5   2 
5   1 
5   1 

結果はこのようになります。

result = 

FREQUENCY_GROUP GRADE_1 GRADE_2 GRADE_3 GRADE_4 GRADE_5 
"1 time"   1   0   0   0   1 
"2-3 times"  3   2   0   0   1 
"> 3 times"  0   2   1   0   1 

私はこれdf.groupby(['EVALUATION_GRADE']).agg({'ID_PERSON': 'count'}).reset_index()を行う場合、私は12345をパット者の合計数を取得します。しかし、どのように周波数グループに分割することができますか?

答えて

3

あなたはcutそして、検索頻度のための最初のsizeで最初transformを使用するためのビンを作成することができますそしてsizeとの最後のgroupbyは、reindexによってunstackによって再形成し、不足している列を入力します。

df['FREQ'] = df.groupby('ID_PERSON')['EVALUATION_GRADE'].transform('size') 
bins = [-np.inf, 1, 3, np.inf] 
labels=['1 time','2-3 times','> 3 times'] 
df.FREQ = pd.cut(df.FREQ, bins=bins, labels=labels) 

df = df.groupby(['FREQ', 'EVALUATION_GRADE'])['EVALUATION_GRADE'] \ 
     .size() \ 
     .unstack(fill_value=0) \ 
     .reindex(columns=np.arange(1,6), fill_value=0) 
df.columns = 'GRADE ' + df.columns.astype(str) 
print (df) 
      GRADE 1 GRADE 2 GRADE 3 GRADE 4 GRADE 5 
FREQ             
1 time   1  0  0  0  1 
2-3 times  3  2  0  0  1 
> 3 times  0  2  1  0  1 
+0

ちょうど理解するために。この 'bins = [-np.inf、1、3、5、np.inf]は' labels = ['1'、 '2-3 times'、 '4-5 times'、 '5'時間 '] '? – user7379562

+0

ええ、私は代わりに問題を参照してください - 必要があれば '0'、申し訳ありません。 – jezrael

+0

私は電話でしかないので、今はテストできません。 – jezrael

1

まあ、基本的な考え方は以下のようになり - ピボットデータに周波数グループを取得するためにGroupBy.transformを使用し、pandas.crosstab.

>>> def worker(x): 
     if len(x) == 1: 
      return "1 time" 
     elif len(x) <=3 : 
      return "2-3 times" 
     else: 
      return "> 3 times" 
>>> df['FREQUENCY_GROUP'] = df.groupby('ID_PERSON').transform(worker) 
>>> df 
    ID_PERSON EVALUATION_GRADE FREQUENCY_GROUP 
0   1     2  > 3 times 
1   1     2  > 3 times 
2   1     3  > 3 times 
3   1     5  > 3 times 
4   2     5   1 time 
5   3     2  2-3 times 
6   3     5  2-3 times 
7   3     1  2-3 times 
8   4     1   1 time 
9   5     2  2-3 times 
10   5     1  2-3 times 
11   5     1  2-3 times 
>>> pd.crosstab(df['FREQUENCY_GROUP'], 'GRADE ' + df['EVALUATION_GRADE'].astype('str')) 
EVALUATION_GRADE GRADE 1 GRADE 2 GRADE 3 GRADE 5 
FREQUENCY_GROUP          
1 time     1  0  0  1 
2-3 times    3  2  0  1 
> 3 times    0  2  1  1 
+0

の任意の数に一般化すべきである答えです2-3回。 – user7379562

+0

また、「ワーカー」とは何ですか? – user7379562

+0

@ user7379562申し訳ありませんが、そこに機能を追加するのを忘れました –

1

はここで `> 3 times`、` 1 time`と `私はあなたが得るかを理解していないグレードやIDS

d = {1: '1 time', 2:'2-3 times', 3:'2-3 times', 4:'> 3 times'} 

df['FREQUENCY_GROUP'] = df.groupby('ID_PERSON')['ID_PERSON']\ 
          .transform('size')\ 
          .clip_upper(4)\ 
          .map(d) 

df1 = df.pivot_table(index='FREQUENCY_GROUP', 
        columns='EVALUATION_GRADE', 
        values='ID_PERSON', 
        aggfunc='count', 
        fill_value=0)\ 
     .reindex(columns=range(df.EVALUATION_GRADE.min(), 
           df.EVALUATION_GRADE.max() + 1), 
       fill_value=0) 

df1.columns = 'GRADE_' + df1.columns.astype(str) 

出力

    GRADE_1 GRADE_2 GRADE_3 GRADE_4 GRADE_5 
FREQUENCY_GROUP            
1 time     1  0  0  0  1 
2-3 times    3  2  0  0  1 
> 3 times    0  2  1  0  1 
関連する問題