Преобразование сгруппированных данных путем преобразования категорий группировки в поля (используя GraphLab или DataFrame Panda)

У меня есть следующие записи, сгруппированные по столбцам user_id и action.

user_id | action | count
1       | read   | 15
1       | write  | 5
1       | delete | 7
2       | write  | 2
3       | read   | 9
3       | write  | 1
3       | delete | 2

Я хочу преобразовать эту таблицу в следующий формат, где каждое действие теперь является столбцом, а строки - значениями счетчика.

user_id | read | write | delete
1       | 15   | 5     | 7
2       | 0    | 2     | 0
3       | 9    | 1     | 2

Я знаю, как сделать это с помощью циклов, но мне любопытно, есть ли более эффективный способ сделать это в GraphLab для создания SFrame или DataFrame Panda.

Я ценю любую помощь!

2 ответа

Решение

Ты можешь использовать pivot с fillna и последний актерский состав float в int от astype:

df = df.pivot(index='ser_id', columns='action', values='count').fillna(0).astype(int)
print (df)
action  delete  read  write
ser_id                     
1            7    15      5
2            0     0      2
3            2     9      1

Другое решение с set_index а также unstack:

df = df.set_index(['ser_id','action'])['count'].unstack(fill_value=0)
print (df)
action  delete  read  write
ser_id                     
1            7    15      5
2            0     0      2
3            2     9      1

Решение, если дублируется в столбце ser_id а также action а также pivot или же unstack не может быть использован groupby с агрегацией mean или же sum и изменить по unstack:

df = df.groupby(['ser_id','action'])['count'].mean().unstack(fill_value=0)
print (df)
action  delete  read  write
ser_id                     
1            7    15      5
2            0     0      2
3            2     9      1

Тайминги:

#random dataframe
np.random.seed(100)
N = 10000
df = pd.DataFrame(np.random.randint(100, size=(N,3)), columns=['user_id','action', 'count'])
#[10000000 rows x 2 columns]
print (df)

In [124]: %timeit (df.groupby(['user_id','action'])['count'].mean().unstack(fill_value=0))
100 loops, best of 3: 5.5 ms per loop

In [125]: %timeit (df.pivot_table('count', 'user_id', 'action', fill_value=0))
10 loops, best of 3: 35.9 ms per loop

Вы можете pivot Это:

df.pivot_table('count', 'user_id', 'action', fill_value=0)

введите описание изображения здесь

Другие вопросы по тегам