如何在Pandas方法链中替换DataFrame特定行的指定值?
问题:将Pandas替换操作整合到方法链中
用户原始代码:
import numpy as np import pandas as pd days = np.arange(0,11) rets = np.array([ 0.00, 0.02, 0.03, 0.04, -0.01, -0.02, 0.01, 0.02, -0.03, -0.05,0.10 ]) start = 100 df = pd.DataFrame({"time": days, "return":rets}) new_df = (df .assign(**{f"lag_{i}":df["return"].add(1).iloc[1:].shift(-i).cumprod() for i in np.arange(6)}) ) new_df.iloc[0] = new_df.iloc[0].replace(np.nan,1) # 希望将此行整合到上方方法链中
期望实现的链式调用结构:
new_df = (df .assign(...) .replace(...) )
解决方案
方法1:用pipe插入自定义替换逻辑
pipe能在链式调用中执行自定义DataFrame操作,专门处理第一行的NaN:
new_df = (df .assign(**{f"lag_{i}": df["return"].add(1).iloc[1:].shift(-i).cumprod() for i in np.arange(6)}) .pipe(lambda df: df.loc[0].replace(np.nan, 1).to_frame().T.combine_first(df)) )
方法2:生成列时直接填充NaN(推荐)
在创建lag_*列的阶段就处理NaN,无需后续替换:
new_df = (df .assign(**{f"lag_{i}": df["return"].add(1).iloc[1:].shift(-i).cumprod().reindex(df.index).fillna(1) for i in np.arange(6)}) )
通过reindex保证列长度匹配原DataFrame,fillna(1)直接将第一行的NaN替换为1,一步完成。
方法3:结合replace与行索引判断
如果一定要用.replace()方法,可通过函数判断行索引来定位替换:
new_df = (df .assign(**{f"lag_{i}": df["return"].add(1).iloc[1:].shift(-i).cumprod() for i in np.arange(6)}) .replace(np.nan, lambda val: 1 if val.name == 0 else val) )
这里val.name对应行索引,当索引为0时(第一行),将NaN替换为1,其他行保持原样。
内容的提问来源于stack exchange,提问作者FredMaster
相关产品推荐
相关产品推荐

