如何在pandas方法链式调用中使用rename正确修改列名
解决方法
你之前的rename写法失效的核心原因是:当给rename的columns参数传入匿名函数时,函数接收的输入是单个列名(此处pivot后是MultiIndex的元组),而非整个DataFrame,所以在函数内调用x.columns会直接报错。
有两种简单的实现方式,都可以完美嵌入链式调用:
方式1:直接传入列名处理函数(更简洁)
因为pivot+reset_index后所有列都是二元组结构,直接对每个列元组做判断处理即可:
import pandas as pd import numpy as np df = pd.DataFrame({'ID':[1,2,2,3,3,3], 'date': ['2021-10-12','2021-10-16','2021-10-15','2021-10-10','2021-10-19','2021-10-01'], 'location':['up','up','down','up','up','down'], 'code':[False, False, False, True, False, False]}) df = (df .assign(date = lambda x: pd.to_datetime(x.date)) .assign(entries_per_ID = lambda x: x.groupby('ID').ID.transform('size')) .pivot_table(values=['entries_per_ID'], index=['ID','date','code'], columns=['location'], aggfunc=np.max) .reset_index() .rename(columns=lambda col: col[0] if col[1] == '' else '_'.join(col).strip()) )
方式2:用pipe获取全量DataFrame后修改(和你原有赋值逻辑完全一致)
如果需要先拿到完整的列列表再做批量映射,可以用pipe拿到中间状态的整个DataFrame,再做重命名:
df = (df .assign(date = lambda x: pd.to_datetime(x.date)) .assign(entries_per_ID = lambda x: x.groupby('ID').ID.transform('size')) .pivot_table(values=['entries_per_ID'], index=['ID','date','code'], columns=['location'], aggfunc=np.max) .reset_index() .pipe(lambda temp_df: temp_df.rename(columns=dict(zip(temp_df.columns, ['_'.join(col).strip() if col[1]!='' else col[0] for col in temp_df.columns.values])))) )
两种方式最终得到的列名都和你单独赋值的结果完全一致:['ID', 'date', 'code', 'entries_per_ID_down', 'entries_per_ID_up']。
内容的提问来源于stack exchange,提问作者corianne1234
相关产品推荐
相关产品推荐

