Pandas函数应用问题:基于条件为DataFrame添加新列
问题解决:Pandas根据多条件匹配生成新列
原代码的问题点
apply调用错误:你写的df.apply(rule(df, dfPP), axis=1)是直接执行了rule函数,而非将函数对象传递给apply。正确方式是传递函数名,并用args参数传入额外的dfPP。- 类型不匹配:
df['Nums']中的元素是字符串(如'89'),但dfPP['Num']是整数(89),直接使用isin会无法匹配。 - 逻辑错误:原函数的条件判断不符合需求,应该先根据
Ser匹配dfPP中对应的SerPP行,再检查该行的Num是否存在于当前行的Nums列表中。
修正后的apply实现方案
import pandas as pd df = pd.DataFrame({ 'Nums':[ ['89' ,'1'], ['89'],['7', '23'],['7', '89', '13','11']], 'Ser': [88858, 54321, 88858, 98547]}) dfPP = pd.DataFrame({ 'Num':[ 5 ,89, 23, 13], 'SerPP': [12345, 54321, 88858, 98547]}) def rule(row, dfPP): # 筛选出与当前行Ser匹配的dfPP记录 matched_rows = dfPP[dfPP['SerPP'] == row['Ser']] # 遍历匹配记录,检查Num转字符串后是否在Nums列表中 for _, pp_row in matched_rows.iterrows(): num_str = str(pp_row['Num']) if num_str in row['Nums']: return [num_str] # 无匹配则返回['0'] return ['0'] # 用apply传递函数,args参数传入dfPP df['New'] = df.apply(rule, args=(dfPP,), axis=1) print(df)
执行后输出符合预期:
Nums Ser New 0 ['89', '1'] 88858 ['0'] 1 ['89'] 54321 ['89'] 2 ['7', '23'] 88858 ['23'] 3 ['7', '89', '13', '11'] 98547 ['13']
更高效的向量化实现(推荐大数据量使用)
apply本质是逐行循环,数据量大时效率较低,推荐用向量化方法实现:
import pandas as pd df = pd.DataFrame({ 'Nums':[ ['89' ,'1'], ['89'],['7', '23'],['7', '89', '13','11']], 'Ser': [88858, 54321, 88858, 98547]}) dfPP = pd.DataFrame({ 'Num':[ 5 ,89, 23, 13], 'SerPP': [12345, 54321, 88858, 98547]}) # 将dfPP的Num转为字符串,统一类型方便匹配 dfPP['Num_str'] = dfPP['Num'].astype(str) # 基于Ser和SerPP合并两个DataFrame merged_df = df.merge(dfPP, left_on='Ser', right_on='SerPP', how='left') # 标记每个合并行是否满足Num_str在Nums中的条件 merged_df['is_match'] = merged_df.apply(lambda x: x['Num_str'] in x['Nums'] if pd.notna(x['Num_str']) else False, axis=1) # 按原df的行索引分组,提取匹配的Num_str,无匹配则返回['0'] df['New'] = merged_df.groupby(merged_df.index)['Num_str'].apply(lambda x: [x[x].iloc[0]] if any(x) else ['0']) print(df)
内容的提问来源于stack exchange,提问作者user534280
相关产品推荐
相关产品推荐

