多DataFrame按ID取最大值并关联对应name的实现问题
问题:多DataFrame按id提取最大值并保留对应name
我有多个包含id、max值与对应name的DataFrame,需要针对每个id提取所有DataFrame中的max最大值,同时保留该最大值所属的name。示例仅展示2个DataFrame,实际有近100个,每个含约100个id,无法手动匹配对应name。尝试用groupby但未得到预期结果,相关代码、当前输出及预期输出如下:
示例代码
import pandas as pd d1 = pd.DataFrame() d2 = pd.DataFrame() d1['id'] = [1,2,3,4,5] d2['id'] = [1,2,3,4,5] d1['max'] = [10,20,30,40,50] d2['max'] = 25 d1['name'] = 'name_1' d2['name'] = 'name_2' df_max_list=[d1, d2] df_max_out=pd.concat(df_max_list).groupby(level=0).max()
当前输出
id max name 0 1 25 name_2 1 2 25 name_2 2 3 30 name_2 3 4 40 name_2 4 5 50 name_2
预期输出
id max name 0 1 25 name_2 1 2 25 name_2 2 3 30 name_1 3 4 40 name_1 4 5 50 name_1
解决方案
之前的groupby(level=0).max()是按原DataFrame的索引分组,对每列单独取最大值——name列会取字符串字典序的最大值(name_2比name_1大),因此无法匹配到最大值对应的name。正确的思路是按id分组,找到每组中max值最大的完整行,保留对应的name。
方法一:排序后取首行
先合并所有DataFrame,按max降序排序后,对每个id取第一行(即max最大的行):
import pandas as pd d1 = pd.DataFrame() d2 = pd.DataFrame() d1['id'] = [1,2,3,4,5] d2['id'] = [1,2,3,4,5] d1['max'] = [10,20,30,40,50] d2['max'] = 25 d1['name'] = 'name_1' d2['name'] = 'name_2' df_max_list = [d1, d2] # 合并所有DataFrame combined_df = pd.concat(df_max_list) # 按id分组,每组按max降序排序后取第一行 df_max_out = combined_df.sort_values('max', ascending=False).groupby('id').first().reset_index(drop=False) # 调整列顺序以匹配预期输出 df_max_out = df_max_out[['id', 'max', 'name']].reset_index(drop=True) print(df_max_out)
方法二:用idxmax定位最大值行
通过idxmax()找到每组中max值最大的行索引,再提取对应行:
import pandas as pd d1 = pd.DataFrame() d2 = pd.DataFrame() d1['id'] = [1,2,3,4,5] d2['id'] = [1,2,3,4,5] d1['max'] = [10,20,30,40,50] d2['max'] = 25 d1['name'] = 'name_1' d2['name'] = 'name_2' df_max_list = [d1, d2] combined_df = pd.concat(df_max_list) # 按id分组,获取每组max值最大的行索引 max_row_indices = combined_df.groupby('id')['max'].idxmax() # 根据索引提取对应行 df_max_out = combined_df.loc[max_row_indices].reset_index(drop=True) # 调整列顺序以匹配预期输出 df_max_out = df_max_out[['id', 'max', 'name']] print(df_max_out)
两种方法都能适配大量DataFrame的场景,无需手动处理,自动完成id匹配、最大值提取及对应name保留。
内容的提问来源于stack exchange,提问作者Regina Phalange
相关产品推荐
相关产品推荐

