如何无需apply+lambda,在嵌套DataFrame中批量填充height列NaN值
嵌套DataFrame批量填充height列缺失值的非apply/lambda方案
问题背景
有一个嵌套结构的DataFrame(实际数据量更大),示例代码如下:
import pandas as pd import numpy as np df_peter = pd.DataFrame({"height": [50,np.nan,65], "weight": [20,25,27]}) df_anna = pd.DataFrame({"height": [47,55,np.nan], "weight": [18,23,30]}) df = pd.DataFrame({"Name":["Peter", "Anna"], "Year":[2000, 2002], "Data":[df_peter, df_anna]})
输出结果:
Name Year Data 0 Peter 2000 height weight 0 50.0 20 1 NaN ... 1 Anna 2002 height weight 0 47.0 18 1 55.0 ...
需求是对每个Name对应的height列使用fillna(method="ffill")填充缺失值,同时要能方便定位这些列并绘制数据。
单行处理逻辑简单:
df.loc[0,"Data"]["height"].fillna(method="ffill")
但批量处理时df["Data"]["height"]无法生效,目前已实现apply+lambda的方案:
df["Data"].apply(lambda x: x["height"].fillna(method="ffill", inplace=True))
希望找到无需apply和lambda的实现方式。
可行方案
方案1:列表推导式生成新子DataFrame列表
通过列表推导式遍历每个子DataFrame,用assign生成填充后的新DataFrame,再赋值回原列,完全避开apply和lambda:
df["Data"] = [sub_df.assign(height=sub_df["height"].fillna(method="ffill")) for sub_df in df["Data"]]
该方式不会修改原始子DataFrame(避免inplace=True的副作用),逻辑清晰且效率可观,适合大数据量场景。
方案2:直接循环遍历修改
如果需要和原inplace=True逻辑一致,直接循环每个子DataFrame执行填充操作即可:
for sub_df in df["Data"]: sub_df["height"].fillna(method="ffill", inplace=True)
这种方式代码简洁,直接对嵌套的子DataFrame原地修改,无需额外生成对象。
方案3:展开嵌套结构(推荐用于可视化)
若后续需要频繁绘制数据,建议先将嵌套DataFrame展开为扁平结构,再统一处理缺失值,更适配pandas的可视化API:
# 展开嵌套结构,保留Name、Year关联信息 flattened_df = df.explode("Data", ignore_index=False).join(pd.DataFrame(df["Data"].tolist(), index=df.index)).reset_index(drop=True) # 批量填充height缺失值 flattened_df["height"] = flattened_df["height"].fillna(method="ffill") # 直接绘制示例 flattened_df.plot(x="Year", y="height", hue="Name")
展开后的结构更直观,无需再嵌套操作,大幅降低数据可视化的复杂度。
内容的提问来源于stack exchange,提问作者Joschi
相关产品推荐
相关产品推荐

