Pivot Pandas Dataframe with duplicatelicates using Masking

时间:2016-12-16 05:40:20

标签: python pandas group-by pivot-table reshape

非索引df包含基因行,包含该基因突变的细胞,以及该基因中的突变类型:

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']})

DF:

  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所以我可以通过基因索引并将列设置为单元格。问题在于每个细胞可能有多个条目:在给定细胞中的任何一个基因中可能存在多个突变(细胞A在基因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

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

drop_duplicatespivot_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_duplicatesgroupby汇总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