2016-12-16 7 views
0

Не-индексированным DF содержит строки гена, ячейку, содержащую мутацию в этом гене, и типа мутации в этом гене:кронштейн Пандас Dataframe с дубликатами с использованием маскирования

df = pd.DataFrame({'gene': ['one','one','one','two','two','two','three'], 
         'cell': ['A', 'A', 'C', 'A', 'B', 'C','A'], 
         'mutation': ['frameshift', 'missense', 'nonsense', '3UTR', '3UTR', '3UTR', '3UTR']}) 

ДФ:

cell gene mutation 
0 A one frameshift 
1 A one missense 
2 C one nonsense 
3 A two  3UTR 
4 B two  3UTR 
5 C two  3UTR 
6 A three  3UTR 

Я хотел бы развернуть этот df, чтобы я мог индексировать ген и устанавливать столбцы в ячейки. Проблема в том, что на ячейку может быть несколько записей: в данной клетке могут быть множественные мутации в любом одном гене (клетка А имеет две разные мутации в гене One). Поэтому, когда я бегу:

df.pivot_table(index='gene', columns='cell', values='mutation') 

это происходит:

DataError: No numeric types to aggregate 

Я хотел бы использовать маскирование для выполнения стержень во время захвата присутствие на минимум один мутации:

 A B C 
gene   
one 1 1 1 
two 0 1 0 
three 1 1 0 

ответ

1

Решение с drop_duplicates и pivot_table:

df = df.drop_duplicates(['cell','gene']) 
     .pivot_table(index='gene', 
        columns='cell', 
        values='mutation', 
        aggfunc=len, 
        fill_value=0) 
print (df) 
cell A B C 
gene   
one 1 0 1 
three 1 0 0 
two 1 1 1 

Другое решение с drop_duplicates, groupby с совокупным size и последней перекроить по unstack:

df = df.drop_duplicates(['cell','gene']) 
     .groupby(['cell', 'gene']) 
     .size() 
     .unstack(0, fill_value=0) 
print (df) 
cell A B C 
gene   
one 1 0 1 
three 1 0 0 
two 1 1 1 
1

Сообщение об ошибке не является тем, что производится при запуске pivot_table. Вы можете иметь несколько значений в индексе для pivot_table. Я не считаю, что это верно для метода pivot. Однако вы можете исправить свою проблему, изменив агрегацию на то, что работает на строки, а не на числовые. Большинство функций агрегации работают с числовыми столбцами, а код, который вы написали выше, приведет к ошибке, связанной с типом данных столбца, а не с ошибкой индекса.

df.pivot_table(index='gene', 
       columns='cell', 
       values='mutation', 
       aggfunc='count', fill_value=0) 

Если вы хотите только 1 значение на ячейку вы можете сделать GroupBy и совокупное все 1, а затем поместить значение уровня.

df.groupby(['cell', 'gene']).agg(lambda x: 1).unstack(fill_value=0)