如何在行级别对Pandas DataFrame执行fillna操作?
解决DataFrame扩展行时保留非指定列原值的问题
你之前操作出现NaN的核心原因:生成的df2只包含id和text的新值,其他列无数据,拼接后自然出现缺失。正确思路是基于原数据的每一行,生成扩展行时直接继承原行的所有非指定列值,而非单独创建空列的df2。以下是两种实用解决方案:
方法一:用explode实现精准扩展(适合自定义扩展内容)
适合为不同原行指定不同扩展数量或内容的场景,比如某行扩展2个新条目,另一行扩展3个。
- 准备原数据
import pandas as pd # 原DataFrame,v_3到v_50列直接保留即可,无需额外处理 df1 = pd.DataFrame({ 'id': ['id_1', 'id_2', 'id_3'], 'text': ['text_1', 'text_2', 'text_3'], 'v_2': ['a', 'b', 'c'] })
- 定义每行的扩展内容
# 自定义每个原id对应的新id列表,可按需修改 expand_id_map = { 'id_1': ['id_1_001', 'id_1_002'], 'id_2': ['id_2_001'], 'id_3': ['id_3_001', 'id_3_002', 'id_3_003'] } # 对应text的扩展内容,需和id的扩展数量匹配 expand_text_map = { 'text_1': ['text_1_001', 'text_1_002'], 'text_2': ['text_2_001'], 'text_3': ['text_3_001', 'text_3_002', 'text_3_003'] }
- 生成扩展行并拼接
# 为原数据添加扩展列(列表格式) df1['new_id'] = df1['id'].map(expand_id_map) df1['new_text'] = df1['text'].map(expand_text_map) # 展开列表列,生成带原非指定列值的扩展行 expanded_rows = df1.explode(['new_id', 'new_text']) \ .drop(columns=['id', 'text']) \ .rename(columns={'new_id': 'id', 'new_text': 'text'}) # 拼接原数据和扩展行,得到最终结果 final_df = pd.concat([df1.drop(columns=['new_id', 'new_text']), expanded_rows], ignore_index=True)
方法二:用repeat实现批量重复(适合固定次数扩展)
如果每一行都需要固定重复N次(比如每行扩展2个新条目),这种方法更高效。
import pandas as pd df1 = pd.DataFrame({ 'id': ['id_1', 'id_2', 'id_3'], 'text': ['text_1', 'text_2', 'text_3'], 'v_2': ['a', 'b', 'c'] }) # 设置每行要扩展的次数 expand_times = 2 # 重复原数据行,生成带原非指定列值的基础扩展数据 repeated_df = df1.loc[df1.index.repeat(expand_times)].reset_index(drop=True) # 生成新的id和text值(示例为原值加序号后缀,可自定义规则) repeated_df['id'] = [f"{orig_id}_new{idx%expand_times +1}" for idx, orig_id in enumerate(repeated_df['id'])] repeated_df['text'] = [f"{orig_text}_new{idx%expand_times +1}" for idx, orig_text in enumerate(repeated_df['text'])] # 拼接原数据和扩展行 final_df = pd.concat([df1, repeated_df], ignore_index=True)
补充说明
你之前用fillna(value=xxx)失效,是因为该方法是整列填充同一个值,无法实现“每行的非指定列和原行一致”的需求。只有在生成扩展行时直接继承原行的非指定列值,才能避免NaN问题。
内容的提问来源于stack exchange,提问作者tw0930
相关产品推荐
相关产品推荐

