如何在Pandas管道合并后使用assign/transform生成新变量?
问题描述
现有两个Pandas DataFrame:
import pandas as pd solar_part = pd.DataFrame( {'pool': 1, 'orig': 635.1}, index = [0] ) solar_aod = pd.DataFrame( {'pool': [1,1,1,1], 'MoP': [1,2,3,4], 'prin': [113.1, 115.3, 456.6, 234.1]} )
尝试通过管道合并后用assign生成新变量时触发错误:
solar_p = ( solar_aod .merge(solar_part, on = ['pool'], how = 'left') .assign(remn = ['prin'] / ['orig']) )
错误信息:TypeError: unsupported operand type(s) for /: 'list' and 'list';仅用引号(如'prin' / 'orig')会触发字符串类型的同类错误。直接通过solar_p.prin / solar_p.orig * 100的写法可行,但需要在管道内完成多个运算,希望实现简洁的管道式操作。
解决方案
错误根源
你使用['prin']和['orig']创建的是Python普通列表,而非引用DataFrame的列对象,因此无法执行数值除法。assign方法中需要通过正确方式访问当前管道中的DataFrame列。
正确的assign写法
有两种简洁的实现方式,支持在管道内一次性定义多个新变量:
- Lambda函数访问DataFrame(通用写法,支持依赖新生成的列)
solar_p = ( solar_aod .merge(solar_part, on=['pool'], how='left') .assign( remn=lambda df: df['prin'] / df['orig'] * 100, # 可继续添加任意多个运算 prin_total_ratio=lambda df: df['prin'] / df['prin'].sum(), orig_gap=lambda df: df['prin'] - df['orig'] ) )
通过lambda df捕获管道中的当前DataFrame,再用df['列名']访问列进行运算,能无缝衔接管道操作,且支持后续新变量依赖前面生成的列。
- 直接引用列属性(更简洁,适用于不依赖新列的场景)
solar_p = ( solar_aod .merge(solar_part, on=['pool'], how='left') .assign(remn=lambda df: df.prin / df.orig * 100) )
结合transform的分组运算场景
如果需要对分组数据做转换(比如按pool分组计算占比),可以在管道中结合groupby和transform实现:
solar_p = ( solar_aod .merge(solar_part, on=['pool'], how='left') .groupby('pool') .transform( lambda df: df.assign( remn=df.prin / df.orig * 100, group_prin_share=df.prin / df.prin.sum() ) ) .reset_index(drop=True) )
内容的提问来源于stack exchange,提问作者Jason Richardson
相关产品推荐
相关产品推荐

