背景
我有以下数据框
import pandas as pd
df = pd.DataFrame({'Result' : [['pos', '+', 'pos', 'positive'], ['neg', 'neg'], [], ['pos']],
'P_ID': [1,2,3,4],
'Gene' : [['kras', 'kras', 'kras', 'egfr'], ['brca', 'brca'], [], ['cd133']],
'N_ID' : ['A1', 'A2', 'A3', 'A4']
})
#rearrange columns
df = df[['P_ID', 'N_ID', 'Gene', 'Result']]
df
P_ID N_ID Gene Result
0 1 A1 [kras, kras, kras, egfr] [pos, +, pos, positive]
1 2 A2 [brca, brca] [neg, neg]
2 3 A3 [] []
3 4 A4 [cd133] [pos]
我使用以下摘自unnest (explode) multiple list 2.0
的代码df.set_index('P_ID').apply(lambda x: x.apply(pd.Series).stack()).ffill().reset_index().drop('level_1', 1)
问题
使用上面的代码,我接近想要的东西。但是,由于第三行Gene
中的Result
和2
列是空列表[]
,因此我得到了该行上方的输出,如下所示:
P_ID N_ID Gene Result
0 1 A1 kras pos
1 1 A1 kras +
2 1 A1 kras pos
3 1 A1 egfr positive
4 2 A2 brca neg
5 2 A2 brca neg
6 3 A3 brca neg
7 4 A4 cd133 pos
相反,我想在下面获得输出,其中下一行6 3 A3 [] []
反映了原始数据框df
,其中包含空列表
所需的输出
P_ID N_ID Gene Result
0 1 A1 kras pos
1 1 A1 kras +
2 1 A1 kras pos
3 1 A1 egfr positive
4 2 A2 brca neg
5 2 A2 brca neg
6 3 A3 [] []
7 4 A4 cd133 pos
问题
如何获得所需的输出?
答案 0 :(得分:2)
让我们尝试一些堆叠和堆叠的魔术。这也会保留空列表。
(df.set_index(['P_ID', 'N_ID'])
.stack()
.str.join(',')
.str.split(',', expand=True)
.stack()
.unstack(-2)
.reset_index(level=[0, 1])
.reset_index(drop=True))
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3
7 4 A4 pos cd133
详细信息
首先,将不被触及的列设置为索引。
df.set_index(['P_ID', 'N_ID'])
Result Gene
P_ID N_ID
1 A1 [pos, +, pos, positive] [kras, kras, kras, egfr]
2 A2 [neg, neg] [brca, brca]
3 A3 [] []
4 A4 [pos] [cd133]
接下来,stack
行。
_.stack()
P_ID N_ID
1 A1 Result [pos, +, pos, positive]
Gene [kras, kras, kras, egfr]
2 A2 Result [neg, neg]
Gene [brca, brca]
3 A3 Result []
Gene []
4 A4 Result [pos]
Gene [cd133]
dtype: object
我们现在有一系列。我们需要将这些元素分解为单独的列。因此,首先加入列表,然后再次拆分。 这可以在您的列表元素本身不包含逗号的情况下起作用(如果没有,请找到另一个分隔符以进行连接和分割)。
_.str.join(',').str.split(',', expand=True)
0 1 2 3
P_ID N_ID
1 A1 Result pos + pos positive
Gene kras kras kras egfr
2 A2 Result neg neg None None
Gene brca brca None None
3 A3 Result None None None
Gene None None None
4 A4 Result pos None None None
Gene cd133 None None None
我们需要摆脱NULL值,因此再次调用stack
。
_.stack()
P_ID N_ID
1 A1 Result 0 pos
1 +
2 pos
3 positive
Gene 0 kras
1 kras
2 kras
3 egfr
2 A2 Result 0 neg
1 neg
Gene 0 brca
1 brca
3 A3 Result 0
Gene 0
4 A4 Result 0 pos
Gene 0 cd133
dtype: object
我们快到了。现在我们希望索引的倒数第二级成为我们的列,因此使用unstack(-2)
(倒数第二级的unstack
)进行堆栈化
_.unstack(-2)
Result Gene
P_ID N_ID
1 A1 0 pos kras
1 + kras
2 pos kras
3 positive egfr
2 A2 0 neg brca
1 neg brca
3 A3 0
4 A4 0 pos cd133
最后,做一些整理工作以获取我们的原始专栏。
_.reset_index(-1, drop=True).reset_index()
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3
7 4 A4 pos cd133
如果您希望空白实际上是列表,请使用applymap
:
_.applymap(lambda x: x if x != '' else []))
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3 [] []
7 4 A4 pos cd133
答案 1 :(得分:2)
调整后unnesting
仍然适用
df=df.applymap(lambda x : [''] if x==[] else x)
unnesting(df,['Gene','Result'])
Out[20]:
Gene Result N_ID P_ID
0 kras pos A1 1
0 kras + A1 1
0 kras pos A1 1
0 egfr positive A1 1
1 brca neg A2 2
1 brca neg A2 2
2 A3 3
3 cd133 pos A4 4