Python 熊猫为每列合并具有不同操作的行

Python 熊猫为每列合并具有不同操作的行,python,pandas,Python,Pandas,我是一个轻量级的熊猫用户,我遇到了一个棘手的情况。我想围绕“case_id”合并数据集的行。合并时,如果字符串是唯一的,我希望“Gene”列将字符串按字母顺序与中间的“->”连接起来。另外,有些列有0,有些列有1,我希望合并时用1代替0 df.groupby('case_id').agg(special_merge) def special_merge(data): //Handle 'Gene' Column ex. KRAS->SMAD4->TP53 //Han

我是一个轻量级的熊猫用户,我遇到了一个棘手的情况。我想围绕“case_id”合并数据集的行。合并时,如果字符串是唯一的,我希望“Gene”列将字符串按字母顺序与中间的“->”连接起来。另外,有些列有0,有些列有1,我希望合并时用1代替0

df.groupby('case_id').agg(special_merge)

def special_merge(data):
    //Handle 'Gene' Column ex. KRAS->SMAD4->TP53
    //Handle 0 vs 1

1) 按大小写排序,基因

2) 应用lambda连接组上的唯一排序字符串

3) 应用max在组上联接二进制变量(通过列掩码定义)

4) 将两个结果合并在一起

binary_cols = df.columns[df.columns.str.contains('^ch_')]

df_case_gene = df.groupby('case_id')['Gene'].agg(lambda x: '->'.join(x.sort_values().unique())).reset_index()

df_case_binary_cols = df.groupby('case_id')[binary_cols].agg('max').reset_index()

df_final = df_case_gene.merge(df_case_binary_cols)

df_最终版本:

  case_id               Gene  ch_a  ch_b  ch_c
0       1  KRAS->SMAD4->TP53     1     0     0
1       2     SMAD000->TP000     0     1     1

根据我对您输入数据的理解,我准备了一个示例数据框。然后您可以看到为创建新数据帧而进行的聚合

orig_df = pd.DataFrame({'case_id':[1,2,3,2,1],'Gene':['KRAS','SMAD4','TP53','SMAD4','OTHER'],'col_X':[1,0,0,1,0], 'col_X2':[0,0,0,0,1})

    case_id Gene    col_X   col_X2
0   1       KRAS    1       0
1   2       SMAD4   0       0
2   3       TP53    0       0
3   2       SMAD4   1       0
4   1       BLAH    0       1

new_df = pd.DataFrame()

#lambda function identifies unique values of Gene and sorts them
new_df['Strings'] = orig_df.groupby('case_id')['Gene'].apply(lambda x: sorted(x.unique())).transform(lambda x: '->'.join(x))

#here, max function is used to take 1 during aggregation if 0's and 1's are present
cols_to_agg = [col for col in orig_df if col.startswith('col_')]
new_df[cols_to_agg] = orig_df.groupby('case_id')[cols_to_agg].agg(max)

    Strings col_X   col_X2
case_id     
1   BLAH->KRAS  1   1
2   SMAD4       1   0
3   TP53        0   0


最后一句不清楚。如果0和1位于不同的列中,并且对每列分别执行操作,那么一列中的1如何取代另一列中的0?或者您只是想将所有0替换为1?另外,要连接的字符串是否已在“基因”列中,或者这将是一个新列,用于连接其他列中的字符串?是的,字符串已在“基因”列中。关于0和1,假设我们有列“X”,其中一行的值为0,另一行的值为1。当这两行合并时,我希望列“X”容纳1。您想给我们看一些示例吗data@Wen-Ben I添加了一个关于X列实现的数据的屏幕截图——我将有多个像X列这样的列,我希望最大值应用于这些列。很抱歉没有详细说明。在上面添加了一个屏幕截图。我们讨论了多少列?列出他们的名字是一种选择吗?可能有数百列。我不确定我理解你所说的名字列表是什么意思。我只是更新了一个有两列的案例的代码。您可以看到我将这些列添加到
cols\u to\u agg
列表中,然后在聚合中使用。你认为识别这数百列最简单的方法是什么?嗯,这是个好问题。我还没想过。我认为可以安全地假设每个列名总是以“ch”开头。不确定这是否有帮助。很抱歉不清楚。我将有多个0或1列。当我合并两行时,一行对列“x”为零,另一行对列“x”为1,我希望合并行中的值为1。现在检查一下,`df.`do是什么?它只是一行greak。它实际上是:df_binary_cols=df.groupby('case_id')[binary_cols].agg('max').reset_index()
  case_id               Gene  ch_a  ch_b  ch_c
0       1  KRAS->SMAD4->TP53     1     0     0
1       2     SMAD000->TP000     0     1     1
orig_df = pd.DataFrame({'case_id':[1,2,3,2,1],'Gene':['KRAS','SMAD4','TP53','SMAD4','OTHER'],'col_X':[1,0,0,1,0], 'col_X2':[0,0,0,0,1})

    case_id Gene    col_X   col_X2
0   1       KRAS    1       0
1   2       SMAD4   0       0
2   3       TP53    0       0
3   2       SMAD4   1       0
4   1       BLAH    0       1

new_df = pd.DataFrame()

#lambda function identifies unique values of Gene and sorts them
new_df['Strings'] = orig_df.groupby('case_id')['Gene'].apply(lambda x: sorted(x.unique())).transform(lambda x: '->'.join(x))

#here, max function is used to take 1 during aggregation if 0's and 1's are present
cols_to_agg = [col for col in orig_df if col.startswith('col_')]
new_df[cols_to_agg] = orig_df.groupby('case_id')[cols_to_agg].agg(max)

    Strings col_X   col_X2
case_id     
1   BLAH->KRAS  1   1
2   SMAD4       1   0
3   TP53        0   0