2017-01-15 2 views
3

У меня есть следующие dataframe имени TTM:В панд, после GroupBy сгруппированных колонна ушла

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 

Когда я сделать

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

я получаю то, что я ожидал (хотя я бы хотел чтобы результаты были под новым лейблом под названием «отношение»):

 clienthostid LoginDaysSum 
0    1   4 
1    3   2 

Но когда я

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

я получаю:

0 1.0 
1 1.5 
  1. Почему лейблы идти? Мне также нужна сгруппированная необходимость «clienthostid», и мне также нужны результаты применения для метки под меткой
  2. Иногда, когда я группирую некоторые из других столбцов, все еще появляется, почему это так, что иногда столбцы исчезают и когда-нибудь остается? есть ли у меня флаг, который делает эти вещи?
  3. В примере, который я дал, когда я подсчитал результаты, показанные на ярлыке «LoginDaysSum», есть ли почему вместо этого добавить новый ярлык для результатов?

Спасибо,

ответ

5

Для возврата DataFrame после groupby 2 возможных решения:

  1. параметров as_index=False что работает хорошо с count, sum, mean функции

  2. reset_index для создания новый столбец от уровней index, более общее решение

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 

Для второго нужно удалить as_index=False и вместо того, чтобы добавить reset_index:

#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 

Почему некоторые столбцы исчезли?

Я думаю, что может быть проблема 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

Я думаю, что ОП нашел ошибку. – chrisaycock

+0

@chrisaycock - похоже, это не ошибка. – jezrael

+0

Хорошее объяснение +1 – ade1e

3

count является встроенный метод для groupby объекта и панды знает, что делать с ним. Есть две другие вещи, которые определяют, как выглядит внешний вид.

#       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 

Когда вы использовали apply панд больше не знает, что делать с колонкой группы, когда вы говорите as_index=False. Он должен верить, что если вы используете apply, вы хотите вернуть именно то, что вы говорите, чтобы вернуться, поэтому он просто выбросит его. Кроме того, у вас есть отдельные скобки вокруг столбца, в котором говорится о том, чтобы работать в серии. Вместо этого используйте as_index=True, чтобы сохранить информацию о столбцах группировки в индексе. Затем выполните его с помощью reset_index, чтобы перенести его с индекса обратно в dataframe. На данный момент не имеет значения, что вы использовали одиночные скобки, потому что после reset_index у вас снова будет датафрейм.

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 
Смежные вопросы