【问题标题】:numpy array of numpy arrays of float numbers becoming an 'object' instead of 'float'numpy 浮点数数组的 numpy 数组成为“对象”而不是“浮点数”
【发布时间】:2021-08-29 11:56:20
【问题描述】:

我有大量数组,每个数组都由 float64 组成,数组长度各不相同。我已将它们附加到一个大型 numpy 数组中 - 但是 numpy 数组的 dtype 是“对象”而不是 float64。我知道这可能是由于长度不同,所以我尝试用零填充不同的长度,但无法将主数组转换为 dtype float。以下是发生这种情况的可重现实例:

import numpy as np

A = [1.0, 2.0]
B = [3.0]
C = [5.0,6.0]
conc = []
conc.append(np.array(A))
conc.append(np.array(B)) #If I skip appending B, I get conc.dtype = float64 
conc.append(np.array(C))
conc = np.array(conc)
print(conc.dtype)

for i in range(0, len(conc)):
  if len(conc[i]) < 2:
    conc[i] = np.append(conc[i], np.zeros(2 - len(conc[i]), dtype = float))
    print(conc[i].dtype)

print(conc, conc.dtype, conc.shape)
#conc = conc.astype(np.float64)

P.S:原始的大数组已经按原样提供给我,实际上是一个不同长度的不同声音的数组(这是一个音频分类问题)。因此,我试图找到在稍后阶段追加零的方法,而不是在创建数组时追加。

【问题讨论】:

  • 如果你把所有东西都填好了,np.stack(conc) 应该创建一个新的二维数组。 astype不能改变conc的形状

标签: python numpy


【解决方案1】:

一种方法是预先分配数组,这是可能的,因为您提前知道大小:

lst = [A, B, C]
shape = (len(lst), len(max(lst, key=len)))
arr = np.zeros(shape)
for i, a in enumerate(lst):
    n = len(a)
    arr[i, :n] = a

如果你想先填充单个数组的方法,你也可以这样做:

N = len(max(lst, key=len))
for i in range(len(lst)):
    n = len(lst[i])
    if n < N:
        lst[i] = np.concatenate((lst[i], np.zeros(N - n)))
arr = np.array(lst)

关键是分配给对象数组或列表的元素不会改变类型。为此,您需要创建一个新数组。

【讨论】:

    【解决方案2】:

    开始 - 大小不同的列表列表(它们也可以是数组):

    In [625]: alist = [[1,2,3],[4,5],[6]]
    

    创建一个数组——本质上是一样的,只是引用列表。 object 需要 dtype,否则我们会收到警告。

    In [626]: arr = np.array(alist, object)
    In [627]: alist
    Out[627]: [[1, 2, 3], [4, 5], [6]]
    In [628]: arr
    Out[628]: array([list([1, 2, 3]), list([4, 5]), list([6])], dtype=object)
    

    无法连接它们:

    In [629]: np.stack(arr)
    Traceback (most recent call last):
      File "<ipython-input-629-5e39aed5411e>", line 1, in <module>
        np.stack(arr)
      File "<__array_function__ internals>", line 5, in stack
      File "/usr/local/lib/python3.8/dist-packages/numpy/core/shape_base.py", line 426, in stack
        raise ValueError('all input arrays must have the same shape')
    ValueError: all input arrays must have the same shape
    

    将列表修改为相同大小(实际上我正在制作新列表):

    In [630]: arr[1]=[4,5,0]; arr[2]=[6,0,0]
    In [631]: arr
    Out[631]: array([list([1, 2, 3]), list([4, 5, 0]), list([6, 0, 0])], dtype=object)
    

    在此调用数组不会改变任何东西:

    In [632]: np.array(arr)
    Out[632]: array([list([1, 2, 3]), list([4, 5, 0]), list([6, 0, 0])], dtype=object)
    

    astype 也无济于事。 astype 无法更改形状或将数组/序列放入单个元素槽中。

    In [633]: arr.astype(int)
    TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
    
    The above exception was the direct cause of the following exception:
    Traceback (most recent call last):
      File "<ipython-input-633-486203c45b85>", line 1, in <module>
        arr.astype(int)
    ValueError: setting an array element with a sequence.
    

    但我可以将stack 应用于此:

    In [634]: np.stack(arr)
    Out[634]: 
    array([[1, 2, 3],
           [4, 5, 0],
           [6, 0, 0]])
    

    另一种选择是将数组转换回列表,然后从中生成数组:

    In [635]: np.array(arr.tolist())
    Out[635]: 
    array([[1, 2, 3],
           [4, 5, 0],
           [6, 0, 0]])
    

    如果我就地修改列表,我会看到 arralist 的变化,因为它们包含相同的引用:

    Out[637]: array([list([1, 2, 3]), list([4, 5]), list([6])], dtype=object)
    In [638]: arr[1].append(0);arr[2].extend([0,0])
    In [639]: arr
    Out[639]: array([list([1, 2, 3]), list([4, 5, 0]), list([6, 0, 0])], dtype=object)
    In [640]: alist
    Out[640]: [[1, 2, 3], [4, 5, 0], [6, 0, 0]]
    

    如果列表/数组包含数组,则不可能进行这种就地更改。 np.append/concatenate 新建一个数组,大量复制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多