如何在Pandas中为DataFrame设置多列?版本兼容报错求解
解决Pandas 2.x中Series二元组赋值给DataFrame多列的报错问题
问题原因
Pandas 2.x对DataFrame.loc赋值的类型兼容性要求更严格。原代码中results.to_numpy().tolist()得到的是包含单个二元组的一维列表([(m1, None)]),而赋值给多列时需要与目标列数匹配的二维结构,新版本的Pandas会对输入的维度做严格校验,因此抛出'list' object has no attribute 'ndim'错误。
正确赋值方法
方法1:将Series转换为DataFrame后赋值
把存储二元组的Series直接转换为两列的DataFrame,结构完全匹配目标列要求,无需额外处理:
from unittest.mock import MagicMock import pandas as pd def test_assign_results() -> None: df = pd.DataFrame([{"is_ok": True, "failed": None, "col1": None, "col2": None}]) m1 = MagicMock() m1.name = "col1_val" results = pd.Series([(m1, None)]) # 关键修改:将Series转为DataFrame,自动拆分为两列 df.loc[df["is_ok"] == 1, ["col1", "col2"]] = pd.DataFrame(results.tolist()) row = df.iloc[0] assert row["col1"].name == "col1_val" assert row["col2"] is None
方法2:保持numpy转换但调整维度
如果一定要用numpy转换,需确保输入是二维数组(每个二元组作为一行),通过reshape调整维度即可:
from unittest.mock import MagicMock import pandas as pd import numpy as np def test_assign_results() -> None: df = pd.DataFrame([{"is_ok": True, "failed": None, "col1": None, "col2": None}]) m1 = MagicMock() m1.name = "col1_val" results = pd.Series([(m1, None)]) # 关键修改:将一维列表转为N行2列的二维数组 df.loc[df["is_ok"] == 1, ["col1", "col2"]] = np.array(results.to_list()).reshape(-1, 2) row = df.iloc[0] assert row["col1"].name == "col1_val" assert row["col2"] is None
原理说明
- Pandas 2.x处理多列赋值时,要求右侧输入必须是二维结构(行数匹配筛选后的行数,列数匹配目标列数)。
- 将Series的二元组列表转为DataFrame时,Pandas会自动把每个二元组的元素拆分为单独列,完美匹配
["col1", "col2"]的列数要求。 - 调整numpy数组维度的方式,本质是把一维的二元组列表转为N行2列的二维数组,让Pandas能正确映射到目标列。
内容的提问来源于stack exchange,提问作者sneg
相关产品推荐
相关产品推荐

