I'm currently working on a test where I have different regions with some associated statistic, and a comma-separated list of genes that lie in those regions. This list will be variable in number, and may not contain anything ("NA").
How can I "melt" this dataframe:
region_id statistic genelist
1 2.5 A, B, C
2 0.5 B, C, D, E
3 3.2 <NA>
4 0.1 E, F
Into something like this:
region_id statistic gene
1 2.5 A
1 2.5 B
1 2.5 C
2 0.5 B
2 0.5 C
2 0.5 D
2 0.5 E
3 3.2 <NA>
4 0.1 E
4 0.1 F
Use the below code, use stack to stack it, after that split on ', ', then stack it again, since we stacked it twice, use unstack to unstack with -2, then reset the index using reset_index with -1, after that do the final reset_index with no parameters:
print(df.set_index(['region_id', 'statistic'])
.stack()
.str.split(', ', expand=True)
.stack()
.unstack(-2)
.reset_index(-1, drop=True)
.reset_index()
)
Use:
# Splitting on , and joining with region_id and statistic columns
val = pd.concat([df.region_id,
df.statistic,
df.genelist.str.split(',', expand=True)],
axis=1)
# Unpivoting and ignoring variable column
m = pd.melt(val, id_vars=['region_id', 'statistic'])\
.loc[:, ['region_id', 'statistic', 'value']]
# Ignoring Null values and sorting based on region_id
m[m.value.notnull()]\
.sort_values('region_id')\
.reset_index(drop=True)\
.rename(columns={'value':'gene'})
region_id statistic gene
1 2.5 A
1 2.5 B
1 2.5 C
2 0.5 B
2 0.5 C
2 0.5 D
2 0.5 E
3 3.2 <NA>
4 0.1 E
4 0.1 F
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With