J'ai des données de score et je souhaite les regrouper par segmentation de score personnalisée.

Id  Date          Score
1   2018-01-01    56
2   2018-01-01    72
3   2018-01-01    91
4   2018-01-01    67
5   2018-01-01    65
6   2018-01-02    75
7   2018-01-02    72
8   2018-01-02    91
9   2018-01-02    82
10  2018-01-02    81

Voici ce que j'attendais

 Date          <60    60-79   80-100
 2018-01-01      1        3        1
 2018-01-02      0        2        3

Ce que j'ai fait c'est

 result = pd.crosstab(df.Date, df.Score)
 result['<60'] = result['1']+ ... + result['59']
 result['60-79'] = result['60']+ ... + result['79']
 result['80-100'] = result['80']+ ... + result['100']

Puis je devrais laisser tomber beaucoup de colonnes

Une meilleure façon de procéder?

3
Nabih Bawazir 16 avril 2018 à 16:58

4 réponses

Meilleure réponse
In [59]: pd.crosstab(
             df.Date,
             pd.cut(df.Score, bins=[0, 60, 79, 100], labels='<60  60-79  80-100'.split()))
Out[59]:
Score       <60  60-79  80-100
Date
2018-01-01    1      3       1
2018-01-02    0      2       3
4
MaxU 16 avril 2018 à 14:11

Vous pouvez utiliser value_counts et transmettre bins dont vous avez besoin

df.groupby('Date').Score.apply(pd.Series.value_counts,bins=[-np.inf, 60, 79, 100]).unstack()
Out[442]: 
            (-inf, 60.0]  (60.0, 79.0]  (79.0, 100.0]
Date                                                 
2018-01-01             1             3              1
2018-01-02             0             2              3
3
YOBEN_S 16 avril 2018 à 14:21

Une façon consiste à utiliser pandas.cut suivi de pandas.pivot_table:

df['Bin'] = pd.cut(df['Score'], [0, 60, 79, 100])

res = df.drop('Id', 1)\
        .pivot_table(index='Date', columns='Bin', aggfunc='count')\
        .fillna(0).astype(int)

print(res)

#              Score                   
# Bin        (0, 60] (60, 79] (79, 100]
# Date                                 
# 2018-01-01       1        3         1
# 2018-01-02       0        2         3
3
jpp 16 avril 2018 à 14:08

Utilisez groupby avec < a href = "http://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html" rel = "nofollow noreferrer"> cut et size:

bins = [-np.inf, 60, 79, 100]
labels = ['<60','60-79','80-100']
df = (df.groupby([df['Date'], pd.cut(df['Score'], bins=bins, labels=labels)])
      .size()
      .unstack(fill_value=0))
print (df)
Score       <60  60-79  80-100
Date                          
2018-01-01    1      3       1
2018-01-02    0      2       3
6
jezrael 16 avril 2018 à 14:10