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