2015-03-13 7 views
1

Я пытаюсь группировать на столбец, содержащий кортежи. Каждый кортеж имеет разную длину.Pandas Groupby: группа ** ** колонка, содержащая кортежи

Я хотел бы выполнить простые групповые операции над этим столбцом кортежей, такие как сумма или счет.

Пример:

df = pd.DataFrame(data={ 
        'col1': [1,2,3,4] , 
        'col2': [('a', 'b'), ('a'), ('b', 'n', 'k'), ('a', 'c', 'k', 'z') ] , 
        }) 

print df 

выходы:

col1   col2 
0  1  (a, b) 
1  2  (a, m) 
2  3  (b, n, k) 
3  4 (a, c, k, z) 

Я хотел бы, чтобы иметь возможность группе по col2 на col1, например с суммой.

Ожидаемый результат будет:

col2  sum_col1 
0  a  7 
1  b  4 
2  c  4 
3  n  3 
3  m  2 
3  k  7 
3  z  4 

Я чувствую, что pd.melt может быть в состоянии использовать, но я не могу видеть, как именно.

ответ

2

Здесь подход с использованием .get_dummies и .melt:

import pandas as pd 
df = pd.DataFrame(data={ 
        'col1': [1,2,3,4] , 
        'col2': [('a', 'b'), ('a'), ('b', 'n', 'k'), ('a', 'c', 'k', 'z') ] , 
        }) 

value_col = 'col1' 
id_col = 'col2' 

Распакуйте кортежей DataFrame:

df = df.join(df.col2.apply(lambda x: pd.Series(x))) 

Создать столбцы со значениями кортежей:

dummy_cols = df.columns.difference(df[[value_col, id_col]].columns) 
dfd = pd.get_dummies(df[dummy_cols | pd.Index([value_col])]) 

продуцирующих:

col1 0_a 0_b 1_b 1_c 1_n 2_k 3_z 
0  1 1 0 1 0 0 0 0 
1  2 1 0 0 0 0 0 0 
2  3 0 1 0 0 1 1 0 
3  4 1 0 0 1 0 1 1 

Тогда .melt это и чистый variable колонна из префиксов:

dfd = pd.melt(dfd, value_vars=dfd.columns.difference([value_col]).tolist(), id_vars=value_col) 
dfd['variable'] = dfd.variable.str.replace(r'\d_', '') 
print dfd.head() 

Уступая:

col1 variable value 
0  1  a  1 
1  2  a  1 
2  3  a  0 
3  4  a  1 
4  1  b  0 

И, наконец, получить свой выход:

dfd[dfd.value != 0].groupby('variable')[value_col].sum() 

    variable 
a   7 
b   4 
c   4 
k   7 
n   3 
z   4 
Name: col1, dtype: int64 
+0

Отлично! Спасибо Primer! Я узнал здесь несколько новых трюков! Вопрос: может ли 'df.columns.difference (df [[value_col, id_col]]. Column)' быть упрощено в 'df.columns.difference ([value_col, id_col])' или есть причина для этой более сложной формы? – knightofni

+0

'df.columns.difference ([value_col, id_col])' также в этом случае. '.difference' - это метод объекта« Index », а подход с безопасным отказом - использовать его с другим объектом« Index ». Но, похоже, он тоже может работать со списками. – Primer

+0

Хорошо, мера безопасности. Отлично, спасибо, праймер. – knightofni

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