我有像这样的Python Pandas DataFrame(NCBI RefSeq的UCSC架构):
chrom exonStart exonEnds name
chr1 100,200,300 110,210,310 gen1
chr1 500,700 600,800 gen2
chr2 50,60,70,80 55,65,75,85 gen3
我希望将exonStarts和exonEnds中的值配对,并将它们作为单独的行放置(保留其余的相应信息):
chrom exonStart exonEnds name
chr1 100 110 gen1
chr1 200 210 gen1
chr1 300 310 gen1
chr1 500 600 gen2
chr1 700 800 gen2
chr2 50 55 gen3
chr2 60 65 gen3
chr2 70 75 gen3
chr2 80 85 gen3
我正在考虑使用python / pandas函数的组合:
拉链,分裂,融化,连续
但不知怎的,它对我不起作用
答案 0 :(得分:3)
在理解中使用zip
和split
pd.DataFrame([
[c, s, e, n]
for c, S, E, n in df.itertuples(index=False)
for s, e in zip(S.split(','), E.split(','))
], columns=df.columns)
chrom exonStart exonEnds name
0 chr1 100 110 gen1
1 chr1 200 210 gen1
2 chr1 300 310 gen1
3 chr1 500 600 gen2
4 chr1 700 800 gen2
5 chr2 50 55 gen3
6 chr2 60 65 gen3
7 chr2 70 75 gen3
8 chr2 80 85 gen3
答案 1 :(得分:2)
这是使用numpy
和intertools.chain
的一种方式。
我们的想法是首先将逗号分隔的字段拆分为列表。然后构造结果数据框,重复或链接值是必要的。
import numpy as np
from itertools import chain
df['exonStart'] = df['exonStart'].str.split(',')
df['exonEnds'] = df['exonEnds'].str.split(',')
lens = list(map(len, df['exonStart']))
res = pd.DataFrame({'chrom': np.repeat(df['chrom'], lens),
'exonStart': list(chain.from_iterable(df['exonStart'])),
'exonEnds': list(chain.from_iterable(df['exonEnds'])),
'name': np.repeat(df['name'], lens)})
print(res)
# chrom exonEnds exonStart name
# 0 chr1 110 100 gen1
# 0 chr1 210 200 gen1
# 0 chr1 310 300 gen1
# 1 chr1 600 500 gen2
# 1 chr1 800 700 gen2
# 2 chr2 55 50 gen3
# 2 chr2 65 60 gen3
# 2 chr2 75 70 gen3
# 2 chr2 85 80 gen3
请注意,您可能希望在此过程结束时将数字列转换为int
。
答案 2 :(得分:1)
我使用unstack
和stack
df.set_index(['chrom','name']).apply(lambda x : x.str.split(','),1).\
stack().apply(pd.Series).stack().unstack(-2).\
reset_index().drop('level_2',1)
Out[1201]:
chrom name exonStart exonEnds
0 chr1 gen1 100 110
1 chr1 gen1 200 210
2 chr1 gen1 300 310
3 chr1 gen2 500 600
4 chr1 gen2 700 800
5 chr2 gen3 50 55
6 chr2 gen3 60 65
7 chr2 gen3 70 75
8 chr2 gen3 80 85