是否可以在 numpy 数组中添加不同长度的行,然后在 python 中向该行添加元素?

Posted

技术标签:

【中文标题】是否可以在 numpy 数组中添加不同长度的行,然后在 python 中向该行添加元素?【英文标题】:Is it possible in numpy array to add rows with different length and then add elements to that rows in python? 【发布时间】:2022-01-22 11:00:53 【问题描述】: Python 版本:3.7.11 numpy 版本:1.21.2

我想要一个 numpy 数组,如下所示:

[
    ["Hi", "Anne"],
    ["How", "are", "you"],
    ["fine"]
]

但是创建这个numpy数组的过程并不简单,如下:

# code block 1一开始我们有一个空的numpy数组。

第一个循环:

# code block 2 row 在第一个循环中添加或

在这个循环中,我们知道我们需要一个新行。

第一个循环内的循环:

该行的

# code block 3 元素将被添加到这个内部循环中。

假设:

没有指定迭代次数,我的意思是:

每行的列数不一样

我们不知道要添加到 numpy 数组的行数。

也许下面的代码示例可以帮助我理解我的观点:

a = [["Hi", "Anne"], ["How", "are", "you"], ["fine"]]

# code block 1: code for creating empty numpy array

for row in a:
    # code block 2: code for creating empty row
    
    for element in row:
        # code block 3: code for appending element to that row or last row
    

问题:

是否可以通过这些步骤创建一个 numpy 数组 (code block #1, #2, #3)?

如果是,怎么做?

【问题讨论】:

请您添加您预期输出的样本吗? 你可以,但它没有意义而且很难。您不应该这样做或将可变长度字符串存储在数组中。列表非常适合您想要的内容。 不可能有非矩形的 numpy 数组。您必须使用占位符值进行填充。 在我给出的示例中,我的预期输出是 [["Hi", "Anne"], ["How", "are", "you"],["fine"]]。 @richardec @ZibaGhane。这就说得通了。请注意,将元素插入数组并不像列表那样简单:您重新分配整个数据缓冲区并且必须将新对象重新分配给原始名称。它的效率要低得多。资料来源:我已经这样做了一段时间,相信我 :) 【参考方案1】:

Numpy 数组没有针对不一致的维度进行优化,因此不是好的做法。您只能通过使元素对象而不是字符串来做到这一点。但就像我说的,numpy 不是解决这个问题的方法。

a = numpy.array([["Hi", "Anne"], ["How", "are", "you"], ["fine"]], dtype=object)

【讨论】:

我是 python 的初学者。那么在这种情况下使用列表会更好更高效吗? 是的,如果你不打算运行非常大的程序,你可以在列表中做大多数事情,这更加灵活 我的数据集很大,有 9019 行,所以在这种情况下,使用列表更好还是 numpy 数组更好? @超级菠萝 使用列表可能没问题。 9019没那么大【参考方案2】:

从嵌套列表开始:

In [99]: alist = [
    ...:     ["Hi", "Anne"],
    ...:     ["How", "are", "you"],
    ...:     ["fine"]
    ...: ]
In [100]: alist
Out[100]: [['Hi', 'Anne'], ['How', 'are', 'you'], ['fine']]

从中创建一个数组:

In [101]: arr = np.array(alist)
<ipython-input-101-3fd8e9bd05a9>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  arr = np.array(alist)
In [102]: arr
Out[102]: 
array([list(['Hi', 'Anne']), list(['How', 'are', 'you']), list(['fine'])],
      dtype=object)

该警告告诉我们,我们正在做一些不寻常的事情,或者至少是次优的。我们可以用dtype=object 取消警告,但结果是一样的。

查看结果 - 这是一个 3 元素数组,其中每个元素都是一个列表。它不是多维数组。我们可以做一个数组数组

In [103]: arr1 = np.array([np.array(el) for el in arr], object)
In [104]: arr1
Out[104]: 
array([array(['Hi', 'Anne'], dtype='<U4'),
       array(['How', 'are', 'you'], dtype='<U3'),
       array(['fine'], dtype='<U4')], dtype=object)

听起来你想用数组复制这个列表构造函数:

在 [107] 中:al = []

     ...: for row in alist:
     ...:     al1 = []
     ...:     for el in row:
     ...:         al1.append(el)
     ...:     al.append(al1)
     ...: 
In [108]: al
Out[108]: [['Hi', 'Anne'], ['How', 'are', 'you'], ['fine']]

但是有几个问题。

没有简单的“空”数组;数组的形状可以是 (0,) 或 (0,3) 或 (3,0,3) 等。

数组没有简单快速的appendnp.append 不符合条件。任何“增长”数组的尝试都会导致创建一个包含完整副本的新数组。列表追加只是添加一个指向旨在增长的对象的指针。

虽然numpy 可以创建字符串 dtype 数组(如 [104] 中),但它没有特殊的字符串处理代码。您仍然必须使用 python 字符串方法来操作这些字符串。

对象 dtype 数组上的数学比数值数组上的数学更容易出错。本质上,它以列表理解的速度进行。

numpy 专为对多维数组进行快速数值运算而设计。想想矩阵乘法,加法之类的事情。即使用作机器学习的垫脚石,数组也需要是数字的和“矩形的”。不规则列表不能用于 ML。

【讨论】:

以上是关于是否可以在 numpy 数组中添加不同长度的行,然后在 python 中向该行添加元素?的主要内容,如果未能解决你的问题,请参考以下文章

带有 SWIG 未知长度数组的 NumPy C 扩展

移除接近相同的行 numpy数组。

将两个不同形状的numpy数组合并到一个数组中

如何在 for 循环中添加不同大小的 numpy 数组条目(类似于 Matlab 的单元格数组)?

在二维 numpy 数组中查找匹配的行

在 numpy 数组中查找多个值的行索引