2013-04-01 3 views
3

Является новым для панд и любопытным, если это слишком сложно для его использования.Хитрое агрегирование с использованием pandas

Пример ввода:

time  person game_id won 
----------------------------------- 
12:34:01 John  3   False 
12:34:04 Ringo 2   True 
12:35:05 John  3   False 
12:36:01 John  3   True 
12:36:12 Ringo 3   True 
12:36:41 Paul  4   False 
12:37:01 George 2   False 
12:37:41 George 2   False 

Он показывает количество людей, играющих количество игр в течение долгого времени. В столбце «Победа» указано, выиграл ли человек или нет в это время.

Что я хочу в качестве вывода, сколько людей выиграло в каждой игре хотя бы один раз. Но и сколько людей играло в игру и никогда выиграло.

Результат:

game_id won  count 
----------------------- 
2   True 1 
      False 1 
3   True 2 
      False 0 
4   True 0 
      False 1 
+1

Нет, не слишком сложно. Вы можете сделать это несколькими строками несколькими способами: я использовал 'groupby' и' .nunique() ', чтобы выполнить трудную часть. (Мне показалось легче подсчитать количество игроков и победителей, а затем вычесть их, чтобы получить победителей.) – DSM

+0

Привет Ясир! Без использования pandas я бы сделал метод, который выполняется примерно в порядке n * log (n). Он работает следующим образом, например, словари: Сначала я сортировал строки по лицу, а затем по игре game_id и в последний раз выигрывал. Затем перебирайте все строки и увеличивайте счетчик для (game_id, won = True), если есть запись «True». Иначе я бы увеличил (game_id, won = False) на один, если есть только False-записи. Наконец, я распечатаю результирующий словарь. Возможно, это более элегантный способ сделать это с помощью панд. –

+0

Спасибо DSM! Если бы вы могли поделиться некоторыми деталями, которые были бы потрясающими. Попытка сделать это для laaaaarge dataset. Таким образом, скорость является ключевой. –

ответ

6

Более или менее то, что @DSM говорил:

In [3]: grouped = df.groupby('game_id') 

In [4]: won = grouped.won.sum() 

In [5]: DataFrame({True: won, False: grouped.person.nunique() - won}).stack() 
Out[5]: 
game_id  
2  False 1 
     True  1 
3  False 0 
     True  2 
4  False 1 
     True  0 
dtype: float64 
+0

Спасибо Чанг, суперзвезда панд! –

4
s1 = (~df.groupby(["game_id", "person"]).won.agg(np.any)).groupby(level=0).sum() 
s2 = df.groupby(["game_id", "won"]).person.agg(lambda s:s.nunique()) 
df2 = s2.unstack() 
df2[False] = s1 
df2.fillna(0).unstack().swaplevel(0, 1).sort_index() 
+0

Спасибо HYRY. Вы также обрабатываете случай с несколькими играми, выигранными тем же человеком, который отлично. –

Смежные вопросы