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

多索引Pandas数据框指定列除以常量返回NaN问题求助

问题:Multi-index DataFrame列运算后全变为NaN

我有一个多级索引的Pandas DataFrame,包含31列,第一级索引对应数据来源文件。需要将特定列的像素值除以整数缩放因子px_to_mm转换为毫米值,这些列原本是浮点类型,但运行代码后目标列全变成了NaN,代码如下:

unique_animals = df.index.get_level_values('File').unique() 
px_to_mm = 791
columns_in_px = ['mouth_x', 'mouth_y', 'stomach_centre_x',
       'stomach_centre_y', 'aboral_organ_x',
       'aboral_organ_y', 'tentacle_1_x',
       'tentacle_1_y', 'tentacle_2_x', 'tentacle_2_y',
        'cilia_1_x', 'cilia_1_y', 
       'cilia_2_x', 'cilia_2_y',  'X_diff_stomach',
       'Y_diff_stomach']

for animal in unique_animals:
    for column in columns_in_px:
        df.loc[animal, column] = df.loc[animal, column] / px_to_mm

DataFrame索引结构

MultiIndex([('CtenoEgg230801_',     0),
        ('CtenoEgg230801_',     1),
        ('CtenoEgg230801_',     2),
        ('CtenoEgg230801_',     3),
        ('CtenoEgg230801_',     4),
        ('CtenoEgg230801_',     5),
        ('CtenoEgg230801_',     6),
        ('CtenoEgg230801_',     7),
        ('CtenoEgg230801_',     8),
        ('CtenoEgg230801_',     9),
        ...
        ('CtenoEgg230802_', 66240),
        ('CtenoEgg230802_', 66241),
        ('CtenoEgg230802_', 66242),
        ('CtenoEgg230802_', 66243),
        ('CtenoEgg230802_', 66244),
        ('CtenoEgg230802_', 66245),
        ('CtenoEgg230802_', 66246),
        ('CtenoEgg230802_', 66247),
        ('CtenoEgg230802_', 66248),
        ('CtenoEgg230802_', 66249)],
       names=['File', None], length=106632)

前几行样本数据

mouth_x mouth_y mouth_likelihood    stomach_centre_x    stomach_centre_y    stomach_centre_likelihood   aboral_organ_x  aboral_organ_y  aboral_organ_likelihood tentacle_1_x    ... X_diff_stomach  Y_diff_stomach  Velocity_stomach    Acceleration_stomach    Theta_mouth_stomach Theta_Velocity_mouth_stomach    Theta_Acceleration_mouth_stomach    Theta_deg_mouth_stomach Height_Index    Frame
File                                                                                        
0   231.626724  233.873352  0.999196    200.364288  191.369202  0.998929    168.946747  140.374954  0.996564    202.717392  ... NaN NaN NaN NaN 0.936630    NaN NaN 53.692184   86.915467   0
1   230.637405  234.197998  0.999158    200.186630  191.611725  0.998900    169.261520  140.385788  0.997088    203.156342  ... -0.177658   0.242523    NaN NaN 0.950049    0.013419    NaN 54.461426   87.094083   1
2   230.883316  233.928162  0.999064    200.056335  191.886490  0.999025    169.505844  139.894012  0.997208    205.199158  ... -0.130295   0.274765    0.304093    NaN 0.938103    -0.011946   -0.025365   53.776596   87.748322   2
3   229.841034  234.385590  0.999249    199.935638  191.638977  0.999073    170.242477  139.233582  0.995122    203.273712  ... -0.120697   -0.247513   0.275373    -0.028720   0.960341    0.022238    0.034185    55.051394   87.569965   3
4   229.045685  234.782135  0.999314    200.159286  191.692688  0.999104    169.480316  138.349838  0.994976    203.242462  ... 0.223648    0.053711    0.230007    -0.045366   0.980226    0.019885    -0.002353   56.191290   88.285329   4

问题原因

直接用df.loc[animal, column]赋值时,Pandas无法正确匹配多级索引的行——因为animal只是第一级索引的值,缺少第二级索引的匹配规则,导致赋值操作没有命中目标数据,最终生成NaN。同时,嵌套循环的方式效率极低,还容易触发索引匹配问题。


解决方法

方法1:批量运算(推荐)

不需要循环,直接选中所有目标列执行除法运算,Pandas会自动处理多级索引:

px_to_mm = 791
columns_in_px = ['mouth_x', 'mouth_y', 'stomach_centre_x',
       'stomach_centre_y', 'aboral_organ_x',
       'aboral_organ_y', 'tentacle_1_x',
       'tentacle_1_y', 'tentacle_2_x', 'tentacle_2_y',
        'cilia_1_x', 'cilia_1_y', 
       'cilia_2_x', 'cilia_2_y',  'X_diff_stomach',
       'Y_diff_stomach']

# 直接对目标列执行运算,自动保留索引结构
df[columns_in_px] = df[columns_in_px] / px_to_mm

方法2:修复索引匹配(不推荐,效率低)

如果一定要用循环,需要用pd.IndexSlice明确指定多级索引的匹配规则:

import pandas as pd

unique_animals = df.index.get_level_values('File').unique() 
px_to_mm = 791
columns_in_px = ['mouth_x', 'mouth_y', 'stomach_centre_x',
       'stomach_centre_y', 'aboral_organ_x',
       'aboral_organ_y', 'tentacle_1_x',
       'tentacle_1_y', 'tentacle_2_x', 'tentacle_2_y',
        'cilia_1_x', 'cilia_1_y', 
       'cilia_2_x', 'cilia_2_y',  'X_diff_stomach',
       'Y_diff_stomach']

for animal in unique_animals:
    for column in columns_in_px:
        # 使用IndexSlice匹配第一级索引为animal的所有行
        df.loc[pd.IndexSlice[animal, :], column] = df.loc[pd.IndexSlice[animal, :], column] / px_to_mm

内容的提问来源于stack exchange,提问作者Amy Hassett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:54:56