You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas通过for循环逐列排序合并DataFrame时出现NaN问题的解决方法

问题根因

出现批量NaN完全是pd.concat的默认对齐规则和现有拼接逻辑不匹配导致的:

  • 每次调用sort_it(num)返回的DataFrame,保留的是原pbr2经过排序后的原始行索引,没有做连续重排

pandas的pd.concat默认会按同名行索引匹配值后再拼接

你每次传入的排序结果是对不同列做升序得到的,不同结果的行索引顺序几乎完全不重叠。索引匹配不上的位置,pandas就会自动填充NaN。

举个实际场景的例子:你拿i=4的排序结果(行索引为87、18、47…)作为初始的total_df,后续拼入i=5的排序结果(行索引为22、131、52…),两个表的行索引几乎没有重合,自然除了能匹配上的列名,所有值都会错位变成NaN。

修正实现

按照你的要求(每列的排序效果和单独调用sort_it(i)的输出完全一致),提供两种适配不同使用场景的可直接运行的写法:

方案1:灵活管理所有列的排序结果,避免硬拼接的问题

适合需要单独调用某列排序结果做后续分析的场景,代码改动幅度最小:

def sort_it(num):
    # 提取Stock列+目标排序列,排序后立刻重置索引,消除原索引带来的对齐冲突
    df = pbr2.iloc[:, [1, num]].sort_values(pbr2.columns[num]).reset_index(drop=True)
    return df

# 用字典存储每列的排序结果,比直接拼DataFrame稳定性高很多
sorted_collect = {}
# 遍历所有需要处理的目标列
for col_idx in range(4, 10):
    col_name = pbr2.columns[col_idx]
    sorted_collect[col_name] = sort_it(col_idx)

# 如果需要把所有列的排序结果拼成一张总表,横向拼接即可
total_df = pd.concat(sorted_collect.values(), axis=1)

核心改动是排序后加reset_index(drop=True),把每个子表的行索引改成从0开始的连续整数,横向拼接时同行位置的内容直接对应,不会因为原索引不匹配产生空值。

方案2:保留全表结构,每列独立排序不互相干扰

适合需要对照不同日期的PBR升序排序结果的场景,不会打乱其他列的原始值:

# 初始化空的结果表
total_df = pd.DataFrame(columns=pbr2.columns)
for col_idx in range(4, 10):
    target_col = pbr2.columns[col_idx]
    # 提取对应列的Stock和数值,按目标列升序排序,重置为连续索引
    sorted_part = pbr2[['Stock', target_col]].sort_values(target_col).reset_index(drop=True)
    # 逐列赋值到总表
    total_df['Stock'] = sorted_part['Stock']
    total_df[target_col] = sorted_part[target_col]

踩坑提醒

  • 对不同列单独做排序得到的结果,行顺序没有任何对应关系,不要靠原行索引做纵向拼接,一定会产生大量错位空值
  • 所有独立的排序子表在拼接前,最好都重置为连续索引,从根源上避免pandas的自动对齐机制带来的意外空值

内容的提问来源于stack exchange,提问作者John.H 1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 12:36:07