【问题标题】:Initialize empty list with same shape as array初始化具有与数组相同形状的空列表
【发布时间】:2015-05-31 03:04:04
【问题描述】:

假设我有一个形状数组:

import numpy as np
a = np.zeros(shape=(3, 4, 2))

看起来像:

print a

[[[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]
  [ 0.  0.]]]

如何创建一个形状相同的空列表,其中每个0. 元素都被一个空的子列表替换?

在上面显示的特定情况下,它看起来像:

[[[[], []]
  [[], []]
  [[], []]
  [[], []]],
 [[[], []]
  [[], []]
  [[], []]
  [[], []]],
 [[[], []]
  [[], []]
  [[], []]
  [[], []]]]

但我需要一种通常适用于任何形状的数组的方法。是否有内置函数可以做到这一点?

【问题讨论】:

  • 当你写'list'和sublist时,你是指Python lists,还是numpy arrays?你打算如何处理这些空的sublists
  • @hpaulj 我的意思是 Python list。在这个问题中,您可以看到我需要对这些列表做什么:stackoverflow.com/q/29300646/1391441

标签: python arrays list numpy


【解决方案1】:

np.empty(shape=(3, 4, 2, 0)) 可能是您正在寻找的。或者更一般地说,np.empty(shape=your_shape+(0,)) 其中 your_shape 是像 (3, 4, 2) 这样的元组。

现在要获取所需的列表列表,您可以调用 tolist 方法:

np.empty(shape=your_shape+(0,)).tolist()

否则,您可以执行一个返回嵌套列表推导的包装函数:

a = [[[[] for j in range(2)] for i in range(4)] for k in range(3)]

如果你想要一个 numpy 数组:

a = np.array(a)

这样的功能可以是:

import copy
def empty(shape):
    if len(shape) == 1:
        return [[] for i in range(shape[0])]
    items = shape[0]
    newshape = shape[1:]
    sublist = empty(newshape)
    return [copy.deepcopy(sublist) for i in range(items)]

你会这样称呼它:

a = empty([3,4,2])

【讨论】:

  • 我没有投反对票,但我会冒险说明原因:我正在寻找一种适用于任何形状数组的通用 解决方案。您的答案仅适用于问题中使用的示例数组。
  • @Gabriel 让我知道这是否是一个更好的答案。
  • 现在要获取所需的列表列表,只需调用tolist 方法:np.empty(shape=a.shape+(0,)).tolist()
  • @JulienSpronc 您答案中的第一行不起作用,它们总是返回一个空列表。该功能似乎有一些问题。首先,empty(newshape) 的调用是什么?这在任何地方都没有定义。
  • 这只是对这个答案的改进。也许@JulienSprock 可以编辑它以包含tolist() 的使用。
【解决方案2】:
>>> a = np.zeros(shape=(3, 4, 2))
>>> r = np.empty((a.shape) + (0, ), dtype=object)
>>> r.fill([])
>>> r.tolist()
[[[[], []], [[], []], [[], []], [[], []]], [[[], []], [[], []], [[], []], [[], []]], [[[], []], [[], []], [[], []], [[], []]]]

【讨论】:

  • 这似乎有两个问题。首先,额外的维度应该是(1,)。其次,r.fill([]) 用相同的列表填充每个单元格。
  • 这对我有用(尽管不需要调用r.fill([]))。 r 的 dtype 无关。
  • 对我也有用,不知道我之前在做什么得到一个空列表。
【解决方案3】:

如果目标是一个多维数组,其中单个项目是 Python 列表,我们需要注意不要生成一个 0 维数组,或者只是一个深度嵌套的列表列表。

一个问题是 numpy 很容易将一个列表(无论是否为空)转换为一个数组。默认情况下,它会尝试创建尽可能高的维度数组。例如

In [58]: np.array([[],[]])
Out[58]: array([], shape=(2, 0), dtype=float64)

没有列表数据类型;最接近的是对象。而生成对象数组最稳妥的方法就是将它们初始化为空,然后填充值:

In [54]: A = np.empty((3,4,2),dtype=object)

In [55]: A[0,0,0]=[] 

In [56]: A[:]=A[0,0,[0]]

In [57]: A
Out[57]: 
array([[[[], []],
        [[], []],
        [[], []],
        [[], []]],

       [[[], []],
        [[], []],
        [[], []],
        [[], []]],

       [[[], []],
        [[], []],
        [[], []],
        [[], []]]], dtype=object)

A[:]=[] 不起作用,因为它将[] 视为(0,) 数组:

ValueError: could not broadcast input array from shape (0) into shape (3,4,2)

[0,0,0][0,0,[0]] 的使用假定为 3d,但这可以通过更多工作推广到 nd。这只是概念验证。

但是你关于遍历这样一个数组的另一个问题让我想知道访问这样一个数组是否与访问一个简单的列表列表相比较。但也许该讨论属于另一个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多