升级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
相关产品推荐
相关产品推荐

