如何在 Pandas 数据框中展开一列

22

我有以下的pandas数据框:

import pandas as pd
import numpy as np
df = pd.DataFrame({
               'fc': [100,100,112,1.3,14,125],
               'sample_id': ['S1','S1','S1','S2','S2','S2'],
               'gene_symbol': ['a', 'b', 'c', 'a', 'b', 'c'],
               })

df = df[['gene_symbol', 'sample_id', 'fc']]
df

这将产生以下结果:

Out[11]:
  gene_symbol sample_id     fc
0           a        S1  100.0
1           b        S1  100.0
2           c        S1  112.0
3           a        S2    1.3
4           b        S2   14.0
5           c        S2  125.0

我该如何扩展sample_id,以便最终获得这样的结果:

gene_symbol    S1   S2
a             100   1.3
b             100   14.0
c             112   125.0
2个回答

27

使用pivot或者unstack函数:

#df = df[['gene_symbol', 'sample_id', 'fc']]
df = df.pivot(index='gene_symbol',columns='sample_id',values='fc')
print (df)
sample_id       S1     S2
gene_symbol              
a            100.0    1.3
b            100.0   14.0
c            112.0  125.0

df = df.set_index(['gene_symbol','sample_id'])['fc'].unstack(fill_value=0)
print (df)
sample_id       S1     S2
gene_symbol              
a            100.0    1.3
b            100.0   14.0
c            112.0  125.0

但如果有重复的情况,需要使用pivot_table或者使用groupby进行聚合操作,mean也可以改为summedian等:

df = pd.DataFrame({
               'fc': [100,100,112,1.3,14,125, 100],
               'sample_id': ['S1','S1','S1','S2','S2','S2', 'S2'],
               'gene_symbol': ['a', 'b', 'c', 'a', 'b', 'c', 'c'],
               })
print (df)
      fc gene_symbol sample_id
0  100.0           a        S1
1  100.0           b        S1
2  112.0           c        S1
3    1.3           a        S2
4   14.0           b        S2
5  125.0           c        S2 <- same c, S2, different fc
6  100.0           c        S2 <- same c, S2, different fc
df = df.pivot(index='gene_symbol',columns='sample_id',values='fc')
ValueError: 索引包含重复条目,无法重新塑形。
df = df.pivot_table(index='gene_symbol',columns='sample_id',values='fc', aggfunc='mean')
print (df)
sample_id       S1     S2
gene_symbol              
a            100.0    1.3
b            100.0   14.0
c            112.0  112.5

df = df.groupby(['gene_symbol','sample_id'])['fc'].mean().unstack(fill_value=0)
print (df)
sample_id       S1     S2
gene_symbol              
a            100.0    1.3
b            100.0   14.0
c            112.0  112.5

编辑:

为了清洁数据,将列名设置为None并使用reset_index

df.columns.name = None
df = df.reset_index()
print (df)
  gene_symbol     S1     S2
0           a  100.0    1.3
1           b  100.0   14.0
2           c  112.0  112.5

非常感谢。我该如何压平索引,以便获得与 OP 中完全相同的结果? - neversaint
1
给我一秒钟。 - jezrael
1
你需要将 gene_symbol 作为索引还是作为列? - jezrael
源代码import pandas as pd data = {"sample_id": [1, 2, 3], "score": [85.6, 90.4, 87.3]} df = pd.DataFrame(data) print(df)翻译样例代码 分数 1 85.6 2 90.4 3 87.3 - neversaint

3

你还可以使用pd.crosstab()方法:

In [82]: pd.crosstab(index=df.gene_symbol, columns=df.sample_id, 
                     values=df.fc, aggfunc='mean') \
    ...:   .rename_axis(None,1) \
    ...:   .reset_index()
    ...:
Out[82]:
  gene_symbol     S1     S2
0           a  100.0    1.3
1           b  100.0   14.0
2           c  112.0  125.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接