Python3.8及以上版本Pandas DataFrame赋值失效问题求助
问题描述
以下代码在Python 3.7及更早版本、Pandas 1.3.5中可正常运行:
import pandas as pd import numpy as np hex_name = '123456abc' multi_sub_dir_id_list = [hex_name, hex_name, hex_name] multi_leaf_node_dirs = ['one', 'two', 'three'] x_dir_multi_index = pd.MultiIndex.from_arrays ([multi_sub_dir_id_list, multi_leaf_node_dirs], names = ['hex_name', 'leaf_name']) leaf_name = 'one' dirpath = '/a/string/path' task_path_str = 'thepath' multi_exec_df = pd.DataFrame (data = None, columns = x_dir_multi_index) multi_exec_df.loc[task_path_str] = np.nan multi_exec_df.loc[task_path_str][hex_name, leaf_name] = dirpath
但在Python 3.8及以上版本(如Python 3.11.0+Pandas 1.5.1、Python3.10.8+Pandas1.5.2)中,执行后后续赋值操作被忽略:
- 预期输出:指定位置(
hex_name='123456abc',leaf_name='one')的值为'/a/string/path',其余为NaN:hex_name leaf_name 123456abc one /a/string/path two NaN three NaN - 实际输出:所有值仍为NaN:
> multi_exec_df.loc[task_path_str] hex_name leaf_name 123456abc one NaN two NaN three NaN Name: thepath, dtype: float64
请问这种写法是否已不再被允许?
原因与解决方案
原因
这种写法属于链式索引赋值(df.loc[...] [...] = value),本身就不是Pandas推荐的规范写法。旧版本中因内部机制差异偶然支持,但在Pandas更新版本中,链式索引会返回数据视图而非原DataFrame的直接引用,导致赋值无法同步到原数据,甚至会触发SettingWithCopyWarning提示。
解决方案
改用单步索引赋值,直接通过.loc一次性定位到目标位置,避免链式操作:
# 替换原有两行赋值代码 multi_exec_df.loc[task_path_str, (hex_name, leaf_name)] = dirpath
如果需要先将整行初始化为NaN,可先构造对应Series再赋值:
multi_exec_df = pd.DataFrame(data=None, columns=x_dir_multi_index) # 构造整行NaN的Series init_row = pd.Series([np.nan]*len(x_dir_multi_index), index=x_dir_multi_index) multi_exec_df.loc[task_path_str] = init_row # 单步赋值目标位置 multi_exec_df.loc[task_path_str, (hex_name, leaf_name)] = dirpath
更简洁的方式是直接构造目标行数据:
multi_exec_df = pd.DataFrame(data=None, columns=x_dir_multi_index) # 初始化空Series,仅给指定位置赋值,其余默认NaN row_data = pd.Series(index=x_dir_multi_index) row_data[(hex_name, leaf_name)] = dirpath multi_exec_df.loc[task_path_str] = row_data
内容的提问来源于stack exchange,提问作者Greg Dougherty
相关产品推荐
相关产品推荐

