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

升级Python版本后np.take()抛出ValueError问题求助

问题:升级Python后np.take处理二维列表报错

升级至最新Python版本后,以下代码运行报错:

diameter2D = [[] for i in range(len(masks))]
noSN = []

np.take(diameter2D, noSN)

错误信息

ValueError                                Traceback (most recent call last)
Cell In[86], line 1
----> 1 type(np.take(diameter2D, noSN))

File <__array_function__ internals>:200, in take(*args, **kwargs)

File ~/.conda/envs/jupyter_3.6/lib/python3.8/site-packages/numpy/core/fromnumeric.py:190, in take(a, indices, axis, out, mode)
     93 @array_function_dispatch(_take_dispatcher)
     94 def take(a, indices, axis=None, out=None, mode='raise'):
     95     """
     96     Take elements from an array along an axis.
     97 
   (...)
    188            [5, 7]])
    189     """
--> 190     return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)

File ~/.conda/envs/jupyter_3.6/lib/python3.8/site-packages/numpy/core/fromnumeric.py:54, in _wrapfunc(obj, method, *args, **kwds)
     52 bound = getattr(obj, method, None)
     53 if bound is None:
---> 54     return _wrapit(obj, method, *args, **kwds)
     56 try:
     57     return bound(*args, **kwds)

File ~/.conda/envs/jupyter_3.6/lib/python3.8/site-packages/numpy/core/fromnumeric.py:43, in _wrapit(obj, method, *args, **kwds)
     41 except AttributeError:
     42     wrap = None
---> 43 result = getattr(asarray(obj), method)(*args, **kwds)
     44 if wrap:
     45     if not isinstance(result, mu.ndarray):

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (44,) + inhomogeneous part.

原代码在旧Python版本可正常运行,已尝试调整axis参数、转换为numpy数组、展平二维列表等操作,但均无法达到预期效果。仅当diameter2D为一维列表时无报错,但输出不符合需求。


解决方案

原因分析

新版本numpy对非均匀形状序列转数组的兼容性更严格:np.take会先尝试将输入的二维列表转为numpy数组,若子列表长度不一致(非均匀结构),新版本会直接抛出错误;而旧版本numpy会默认创建object类型数组,绕过形状检查。

具体解决方法

方法1:用Python列表推导式替代np.take

无需依赖numpy,直接通过列表推导提取目标元素,完全保留原二维结构:

result = [diameter2D[i] for i in noSN]

方法2:显式转为object类型numpy数组后调用take

如果必须使用numpy方法,先强制将列表转为dtype=object的数组,避免形状检查:

diameter2D_arr = np.array(diameter2D, dtype=object)
result = np.take(diameter2D_arr, noSN)

返回结果为object类型数组,内部元素仍为原二维列表的子列表。

方法3:统一二维列表形状(业务允许时)

若业务可接受填充值,将diameter2D处理为均匀长度的二维结构,再使用np.take:

max_len = max(len(sub) for sub in diameter2D)
# 用np.nan填充短子列表到统一长度
diameter2D_padded = [sub + [np.nan]*(max_len - len(sub)) for sub in diameter2D]
result = np.take(diameter2D_padded, noSN)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:13:12