Pandas合并空DataFrame后Apply/Assign函数异常问题求助
处理空DataFrame时的Apply/Assign列生成问题
问题场景
对Pandas DataFrame执行操作时,过滤条件可能导致DataFrame为空。当DataFrame有数据时,Apply/Assign能正常生成新列,但空DataFrame时会出现报错或结果不符合预期的情况。
错误示例1:Assign + np.where报错
原代码因np.where语法错误,加上空DataFrame的数组形状不匹配,抛出ValueError: operands could not be broadcast together with shapes (0,) () (3,):
import pandas as pd import numpy as np df1 = pd.DataFrame({'A': [], 'B': [], 'p': []}) df2 = pd.DataFrame({'A': [], 'B': [], 'q': []}) merged_df = pd.merge(df1, df2, on='A', suffixes=('', '_d'))\ .assign(D=lambda x: np.where(((x['B'] == 4) & (x['B_d'] == 7) & (x['p'] < x['q'])), 'Y', (((x['B'] == 5) & (x['B_d'] == 8) & (x['p'] > x['q'])),'N','NA') )) print(merged_df)
错误原因:嵌套条件的写法错误,第二个分支用了元组而非嵌套np.where,空DataFrame时布尔数组形状与后续值的形状不匹配,导致广播失败。
错误示例2:Apply无报错但结果不符合预期
原Apply未指定axis=1,默认按列处理而非按行,空DataFrame时无有效输出:
merged_df1 = pd.merge(df1, df2, on='A', suffixes=('', '_d'))\ .apply(lambda x: 'Y' if (x['B'] == 4) & (x['B_d'] == 7) & (x['p'] < x['q']) else 'N' if (x['B'] == 5) & (x['B_d'] == 8) & (x['p'] > x['q']) else None ) print(merged_df1)
错误原因:默认axis=0时,lambda接收的是列数据而非行数据,无法实现逐行判断逻辑;空DataFrame时,按列处理自然无有效结果。
解决方案
方案1:修复np.where嵌套逻辑
将嵌套条件改为正确的np.where嵌套,确保空DataFrame时形状匹配:
import pandas as pd import numpy as np df1 = pd.DataFrame({'A': [], 'B': [], 'p': []}) df2 = pd.DataFrame({'A': [], 'B': [], 'q': []}) merged_df = pd.merge(df1, df2, on='A', suffixes=('', '_d'))\ .assign(D=lambda x: np.where( (x['B'] == 4) & (x['B_d'] == 7) & (x['p'] < x['q']), 'Y', np.where( (x['B'] == 5) & (x['B_d'] == 8) & (x['p'] > x['q']), 'N', 'NA' ) )) print(merged_df)
空DataFrame时会生成包含空D列的结果,无报错。
方案2:正确使用Apply(指定axis=1)
指定axis=1实现逐行判断,可提前判断DataFrame是否为空以优化性能:
import pandas as pd import numpy as np df1 = pd.DataFrame({'A': [], 'B': [], 'p': []}) df2 = pd.DataFrame({'A': [], 'B': [], 'q': []}) merged_df1 = pd.merge(df1, df2, on='A', suffixes=('', '_d')) if not merged_df1.empty: merged_df1['D'] = merged_df1.apply( lambda row: 'Y' if (row['B'] == 4) & (row['B_d'] == 7) & (row['p'] < row['q']) else 'N' if (row['B'] == 5) & (row['B_d'] == 8) & (row['p'] > row['q']) else 'NA', axis=1 ) print(merged_df1)
空DataFrame时直接输出原合并结果,非空时按逻辑生成D列。
内容的提问来源于stack exchange,提问作者Roshan
相关产品推荐
相关产品推荐

