Pandas DataFrame嵌套列表赋值异常:[[2]]赋值后变为[2]
Pandas赋值二维嵌套列表/数组时被展开的问题及解决方法
当尝试用df.loc['y','A'] = [[2]]给Pandas DataFrame的单个单元格赋值二维嵌套列表时,实际结果会变成[2];类似的,二维object类型numpy数组np.array([[2]], dtype=object)、二维列表[[1],[2]]都会出现被“展开”的异常,但嵌套层数为1层([2])或3层及以上([[[3]]]、[[[[4]]]])的结构赋值正常。更特殊的是,移除DataFrame中的数值型列(例中的C列)后,所有赋值操作都能正常保留嵌套结构。
复现代码及输出
import pandas as pd import numpy as np df = pd.DataFrame({"A": [[1], [[2]], [[[3]]], [[[[4]]]], np.array([[2]]), np.array([[[2]]]), [[1],[2]]], "B": [[1], [[2]], [[[3]]], [[[[4]]]], np.array([[2]]), np.array([[[2]]]), [[1],[2]]], "C": [1,2,3,4,5,6,7] }, index=["x", "y", "z", "w","a","b","c"]) # 初始状态正常 print(df) # 赋值操作 df.loc['x','A'] = [1] # 正常 df.loc['y','A'] = [[2]] # 异常,结果为[2] df.loc['z','A'] = [[[3]]] # 正常 df.loc['w','A'] = [[[[4]]]] # 正常 df.loc['a','A'] = np.array([[2]], dtype=object) # 异常,结果为[2] df.loc['b','A'] = np.array([[[2]]], dtype=object) # 正常 df.loc['c','A'] = [[1],[2]] # 异常,结果为[1,2] print(df)
输出:
A B C x [1] [1] 1 y [[2]] [[2]] 2 z [[[3]]] [[[3]]] 3 w [[[[4]]]] [[[[4]]]] 4 a [[2]] [[2]] 5 b [[[2]]] [[[2]]] 6 c [[1], [2]] [[1], [2]] 7 A B C x [1] [1] 1 y [2] [[2]] 2 z [[[3]]] [[[3]]] 3 w [[[[4]]]] [[[[4]]]] 4 a [2] [[2]] 5 b [[[2]]] [[[2]]] 6 c [1, 2] [[1], [2]] 7
问题原因
这是Pandas的维度匹配与广播逻辑导致的:当DataFrame中存在数值型列(如示例中的C列,类型为int),Pandas在处理loc赋值时,会默认尝试将二维结构的赋值内容与DataFrame的行维度进行匹配,误将二维嵌套结构“展开”为一维。而当移除数值型列后,所有列都为object类型,Pandas会直接将嵌套结构视为单个object值,不会触发维度匹配逻辑,因此赋值正常。
解决方案
有两种可靠的方法避免这个问题:
方法1:使用df.at替代df.loc
at专门用于单个单元格的快速赋值,不会触发维度广播逻辑,直接将嵌套结构作为单个值存入单元格:
# 修正后的赋值代码 df.at['y','A'] = [[2]] df.at['a','A'] = np.array([[2]], dtype=object) df.at['c','A'] = [[1],[2]]
方法2:将嵌套结构包裹在一个外层列表中
通过在外层添加一个列表,强制Pandas将内部的嵌套结构识别为单个单元格值,而非需要广播的序列:
df.loc['y','A'] = [ [[2]] ] df.loc['a','A'] = [ np.array([[2]], dtype=object) ] df.loc['c','A'] = [ [[1],[2]] ]
验证结果
使用上述方法后,再次打印DataFrame,会发现所有嵌套结构都被正确保留:
A B C x [1] [1] 1 y [[2]] [[2]] 2 z [[[3]]] [[[3]]] 3 w [[[[4]]]] [[[[4]]]] 4 a [[2]] [[2]] 5 b [[[2]]] [[[2]]] 6 c [[1], [2]] [[1], [2]] 7
内容的提问来源于stack exchange,提问作者Jian Wang
相关产品推荐
相关产品推荐

