答案 0 :(得分:2)
在这里,df
是您的Pandas DataFrame。
def new_1(g):
return ','.join(g.gene)
def new_2(g):
return ','.join(g.gene + '-' + g.status)
new_1_data = df.groupby("sample").apply(new_1).to_frame(name="new_1")
new_2_data = df.groupby("sample").apply(new_2).to_frame(name="new_2")
new_data = pd.merge(new_1_data, new_2_data, on="sample")
new_df = pd.merge(df, new_data, on="sample").drop_duplicates("sample")
如果您希望将“样本”作为列而不是索引,请添加
new_df = new_df.reset_index(drop=True)
最后,由于您没有指定要保留的原始重复行中的哪一部分,因此我仅使用Pandas的默认行为,并删除除了第一次出现的所有重复行。
我将您的示例转换为以下CSV文件(以','分隔),我将其称为“ data.csv”。
sample,gene,status
ppar,p53,gain
ppar,gata,gain
ppar,nb,loss
srty,nf1,gain
srty,cat,gain
srty,cd23,gain
tygd,brac1,loss
tygd,brac2,gain
tygd,ras,loss
我将此数据加载为
# Default delimiter is ','. Pass `sep` argument to specify delimiter.
df = pd.read_csv("data.csv")
运行上面的代码并打印数据框会产生输出
sample gene status new_1 new_2
0 ppar p53 gain p53,gata,nb p53-gain,gata-gain,nb-loss
3 srty nf1 gain nf1,cat,cd23 nf1-gain,cat-gain,cd23-gain
6 tygd brac1 loss brac1,brac2,ras brac1-loss,brac2-gain,ras-loss
这正是您的示例中给出的预期输出。
请注意,数字的最左列(0、3、6)是合并后生成的原始数据帧的索引的剩余部分。当您将此数据帧写入文件时,可以通过将index=False
设置为df.to_csv(...)
来排除它。
我检查了您通过电子邮件发送给我的CSV文件。 您的CSV文件标题中的“基因”一词后面有一个空格。
从更改CSV文件的第一行
sample,gene ,status
到
sample,gene,status
此外,您的输入中还有空格。如果您希望删除它们,可以
# Strip spaces from entries. Only works for string entries
df = df.applymap(lambda x: x.strip())
答案 1 :(得分:1)
可能不是最有效的解决方案,但这应该可以帮助您:
samples = []
genes= []
statuses = []
for s in set(df["sample"]):
#grab unique samples
samples.append(s)
#get the genes for each sample and concatenate them
g = df["gene"][df["sample"]==s].str.cat(sep=",")
genes.append(g)
#loop through the genes for the sample and get the statuses
status = ''
for gene in g.split(","):
gene_status = df["status"][(df["sample"] == s) & (df["gene"] == gene)].to_string(index=False)
status += gene
status += "-"
status += gene_status
status += ','
statuses.append(status)
#create new df
new_df = pd.DataFrame({'sample': samples,
'new': genes,
'new1': statuses})