gpt4 book ai didi

python - 在 Pandas 中取消嵌套列时保留空列表

转载 作者:太空宇宙 更新时间:2023-11-03 14:37:40 26 4
gpt4 key购买 nike

背景

我有以下数据框

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)

问题

使用上面的代码,我接近了我想要的。但是,因为第三行 2 中的 GeneResult 列是空列表 [],所以我得到它上面一行的输出如下所示:

 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 [] [] 反射(reflect)了原始数据帧 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

问题

如何获得所需的输出?

最佳答案

让我们尝试一些堆叠和取消堆叠的魔法。这也会保留空列表。

(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()

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

关于python - 在 Pandas 中取消嵌套列时保留空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56420074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com