根据另一列的条件连接一列的字符串

时间:2019-03-05 01:38:49

标签: python pandas

我有一个数据框,我想删除名为“ sample”的列上的重复项,并将基因和状态列中的字符串信息添加到新列中,如所附图片所示。

非常感谢您

enter image description here

下面是数据框的修改版本。其中行中的基因被实际的基因名称替换enter image description here

2 个答案:

答案 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(...)来排除它。

编辑2

我检查了您通过电子邮件发送给我的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})