2017-01-15 8 views
3

ich die folgende Datenrahmen genannt TTM gegangen ist:In Pandas, nach groupby die gruppierte Spalte

usersidid clienthostid eventSumTotal LoginDaysSum score 
0  12   1    60    3   1728 
1  11   1    240    3   1331 
3  5   1    5    3   125 
4  6   1    16    2   216 
2  10   3    270    3   1000 
5  8   3    18    2   512 

Wenn ich

tun
ttm.groupby(['clienthostid'], as_index=False, sort=False)['LoginDaysSum'].count() 

ich bekommen, was ich erwartet hatte (obwohl ich gewünscht haben würde die Ergebnisse unter einem neuen Label namens ‚Verhältnis‘) zu sein:

 clienthostid LoginDaysSum 
0    1   4 
1    3   2 

Aber wenn ich

ttm.groupby(['clienthostid'], as_index=False, sort=False)['LoginDaysSum'].apply(lambda x: x.iloc[0]/x.iloc[1]) 

ich:

0 1.0 
1 1.5 
  1. Warum haben die Etiketten gehen? Ich brauche auch noch die gruppierten brauchen die 'clienthostid' und ich brauche auch die Ergebnisse der Anwendung unter einem Etikett zu sein
  2. Manchmal, wenn ich Groupbyby einige der anderen Spalten immer noch erscheinen, warum ist das, dass manchmal Spalten verschwinden und bleibt irgendwann? Gibt es eine Flagge, die ich vermisse?
  3. In dem Beispiel, das ich gab, wenn ich die Ergebnisse auf Label 'LoginDaysSum' gezählt habe, gibt es einen Grund, ein neues Label für die Ergebnisse stattdessen hinzuzufügen?

Danke,

Antwort

5

Für Rückkehr DataFrame nach groupby 2 mögliche Lösungen sind:

  1. Parameter as_index=False was mit count schön funktioniert, sum, mean Funktionen

  2. reset_index für erstellen neue Spalte aus den Ebenen index, allgemeinere Lösung

df = ttm.groupby(['clienthostid'], as_index=False, sort=False)['LoginDaysSum'].count() 
print (df) 
    clienthostid LoginDaysSum 
0    1    4 
1    3    2 
df = ttm.groupby(['clienthostid'], sort=False)['LoginDaysSum'].count().reset_index() 
print (df) 
    clienthostid LoginDaysSum 
0    1    4 
1    3    2 

für die zweite braucht as_index=False zu entfernen und stattdessen reset_index hinzufügen:

#output is `Series` 
a = ttm.groupby(['clienthostid'], sort=False)['LoginDaysSum'] \ 
     .apply(lambda x: x.iloc[0]/x.iloc[1]) 
print (a) 
clienthostid 
1 1.0 
3 1.5 
Name: LoginDaysSum, dtype: float64 

print (type(a)) 
<class 'pandas.core.series.Series'> 

print (a.index) 
Int64Index([1, 3], dtype='int64', name='clienthostid') 


df1 = ttm.groupby(['clienthostid'], sort=False)['LoginDaysSum'] 
     .apply(lambda x: x.iloc[0]/x.iloc[1]).reset_index(name='ratio') 
print (df1) 
    clienthostid ratio 
0    1 1.0 
1    3 1.5 

Warum sind einige Spalten gegangen?

ich denke, es Problem sein kann automatic exclusion of nuisance columns:

#convert column to str 
ttm.usersidid = ttm.usersidid.astype(str) + 'aa' 
print (ttm) 
    usersidid clienthostid eventSumTotal LoginDaysSum score 
0  12aa    1    60    3 1728 
1  11aa    1   240    3 1331 
3  5aa    1    5    3 125 
4  6aa    1    16    2 216 
2  10aa    3   270    3 1000 
5  8aa    3    18    2 512 

#removed str column userid 
a = ttm.groupby(['clienthostid'], sort=False).sum() 
print (a) 
       eventSumTotal LoginDaysSum score 
clienthostid          
1      321   11 3400 
3      288    5 1512 

What is the difference between size and count in pandas?

+0

Ich denke, die OP einen Fehler gefunden hat. – chrisaycock

+0

@chrisaycock - es scheint, es ist kein Fehler. – jezrael

+0

Schöne Erklärung +1 – ade1e

3

count ein in Verfahren zum groupby Objekt gebaut und Pandas weiß, was mit ihm zu tun. Es werden noch zwei andere Dinge spezifiziert, die dazu dienen, zu bestimmen, wie der Ausgang aussieht.

#       For a built in method, when 
#       you don't want the group column 
#       as the index, pandas keeps it in 
#       as a column. 
#        |----||||----| 
ttm.groupby(['clienthostid'], as_index=False, sort=False)['LoginDaysSum'].count() 

    clienthostid LoginDaysSum 
0    1    4 
1    3    2 

#       For a built in method, when 
#       you do want the group column 
#       as the index, then... 
#        |----||||---| 
ttm.groupby(['clienthostid'], as_index=True, sort=False)['LoginDaysSum'].count() 
#              |-----||||-----| 
#             the single brackets tells 
#             pandas to operate on a series 
#             in this case, count the series 

clienthostid 
1 4 
3 2 
Name: LoginDaysSum, dtype: int64 

ttm.groupby(['clienthostid'], as_index=True, sort=False)[['LoginDaysSum']].count() 
#              |------||||------| 
#            the double brackets tells pandas 
#            to operate on the dataframe 
#            specified by these columns and will 
#            return a dataframe 

       LoginDaysSum 
clienthostid    
1      4 
3      2 

Wenn verwendet man apply Pandas nicht mehr weiß, was mit der Gruppenspalte zu tun, wenn Sie as_index=False sagen. Es muss darauf vertrauen, dass, wenn Sie apply verwenden, Sie zurückgegeben genau das, was Sie sagen, um zurückzukehren, so wird es einfach wegwerfen. Außerdem haben Sie einzelne Klammern um Ihre Spalte, die besagt, dass Sie in einer Serie arbeiten sollen. Verwenden Sie stattdessen as_index=True, um die Gruppierungsspalteninformationen im Index zu behalten. Dann folgen Sie es mit einer reset_index, um es aus dem Index zurück in den Datenrahmen zu übertragen. An dieser Stelle wird es nicht darauf ankommen, dass Sie einzelne Klammern verwenden, denn nach reset_index haben Sie wieder einen Datenrahmen.

ttm.groupby(['clienthostid'], as_index=True, sort=False)['LoginDaysSum'].apply(lambda x: x.iloc[0]/x.iloc[1]) 

0 1.0 
1 1.5 
dtype: float64 

ttm.groupby(['clienthostid'], as_index=True, sort=False)['LoginDaysSum'].apply(lambda x: x.iloc[0]/x.iloc[1]).reset_index() 

    clienthostid LoginDaysSum 
0    1   1.0 
1    3   1.5