2017-01-05 6 views
4

Ich möchte wissen, wie viele Menschen GRADE 1, 2, 3, 4 und 5 zu den Gruppen von Menschen putted, die die Bewertungen 1 mal, zwischen 2 und 3 mal und mehr als 3 mal gemacht haben. Zum Beispiel enthält die Gruppe von Personen, die die Bewertungen einmal durchführen, Personen mit der ID 2 und 4. In dieser Gruppe gibt es insgesamt eine Auswertung 5 und eine Auswertung 1. Ich bekomme Gesamtzahl der PersonenWie gruppiert man Reihen nach Häufigkeit?

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 

Wenn ich diese df.groupby(['EVALUATION_GRADE']).agg({'ID_PERSON': 'count'}).reset_index() tun, dann die 1, 2, 3, 4 und 5 geputtet:

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 

Das Ergebnis sollte diese sein. Wie kann ich sie in Frequenzgruppen aufteilen?

Antwort

3

Sie zuerst transform mit size zuerst finden Frequenz verwenden können, dann cut für erstellen Bins und zuletzt groupby mit size, neu zu gestalten, indem unstack und füllen fehlende Spalten von reindex:

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

Nur zu verstehen. Würden diese 'Bins = [-np.inf, 1, 3, 5, np.inf]' diese 'Labels = [' 1 mal ',' 2-3 mal ',' 4-5 mal ','> 5 bedeuten mal '] '? – user7379562

+0

Ya, sehe ich Problem stattdessen -inf brauchen '0', sorry. – jezrael

+0

Ich kann es jetzt nicht testen, weil ich nur telefoniere. – jezrael

1

Nun könnte grundlegende Idee wie folgt - GroupBy.transform verwenden Frequenzgruppen zu bekommen und dann pandas.crosstab. Daten zu schwenken:

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

Ich verstehe nicht, wie Sie erhalten verallgemeinern sollten Sie '> 3 times',' 1 Time' und ' 2-3 mal. – user7379562

+0

Auch, was ist 'Arbeiter'? – user7379562

+0

@ user7379562 Entschuldigung vergessen, die Funktion dort hinzuzufügen –

1

Hier ist eine Antwort, die auf eine beliebige Anzahl von Klassen oder 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) 

Ausgang

    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 
Verwandte Themen