【问题标题】:Numpy's "shape" function returns a 1D value for a 2D arrayNumpy“形状”函数返回二维数组的一维值
【发布时间】:2021-05-31 17:05:15
【问题描述】:

所以我创建了这个数组作为例子:

a = np.array([[1, 1, 1, 1, 2], [2, 2, 2, 3], [3, 3, 3, 4], [13, 49, 13, 49], [10, 10, 2, 2],
             [11, 1, 1, 1, 2], [22, 2, 2, 3], [33, 3, 3, 4], [133, 49, 13, 49], [100, 10, 2, 2],
             [5, 1, 1, 1, 2], [32, 2, 2, 3], [322, 3, 3, 4], [13222, 49, 13, 49], [130, 10, 2, 2]])

我想创建一个二维数组。因此,例如在这种情况下,15*5 数组。

但是,当我使用a.shape 时,它会返回(15,)

我的数组定义有什么问题?

【问题讨论】:

    标签: python arrays python-3.x numpy multidimensional-array


    【解决方案1】:

    看看a.dtype:对象是O。当您尝试输入参差不齐的数组时,通常会发生这种情况。在这种情况下,您可以看到只有索引 0、5、10 处的元素实际上有五个元素。所有其他子列表都有四个元素。如果你想要一个(15, 5) 数组,你需要确保每行有5个元素。

    【讨论】:

      【解决方案2】:

      检查你的数组到底是什么:

      import numpy as np
      
      a = np.array([[1, 1, 1, 1, 2], [2, 2, 2, 3], [3, 3, 3, 4], [13, 49, 13, 49], [10, 10, 2, 2],
                   [11, 1, 1, 1, 2], [22, 2, 2, 3], [33, 3, 3, 4], [133, 49, 13, 49], [100, 10, 2, 2],
                   [5, 1, 1, 1, 2], [32, 2, 2, 3], [322, 3, 3, 4], [13222, 49, 13, 49], [130, 10, 2, 2]])
      
      print(repr(a))
      

      它是一个列表对象的数组:

      array([list([1, 1, 1, 1, 2]), list([2, 2, 2, 3]), list([3, 3, 3, 4]),
             list([13, 49, 13, 49]), list([10, 10, 2, 2]),
             list([11, 1, 1, 1, 2]), list([22, 2, 2, 3]), list([33, 3, 3, 4]),
             list([133, 49, 13, 49]), list([100, 10, 2, 2]),
             list([5, 1, 1, 1, 2]), list([32, 2, 2, 3]), list([322, 3, 3, 4]),
             list([13222, 49, 13, 49]), list([130, 10, 2, 2])], dtype=object)
      

      问题在于每个子列表中的元素数量各不相同(有些是 4,有些是 5),所以它只能存储为列表的一维数组。要获得二维数组,子列表中的元素数量必须相等。

      【讨论】:

      • 终于有人回答了这个问题。
      【解决方案3】:

      您的示例中的问题是某些行有 5 个元素,而其他行有 4 个元素。 结果,numpy 无法创建它的 15*5 数组。 它在你的情况下抱怨:

      不推荐从不规则的嵌套序列(它是列表或元组的列表或元组或具有不同长度或形状的 ndarray 的列表或元组)创建 ndarray。

      根据 Terasa 的说法,“原始数据存在一些根本性的错误处理/误解”。 所以你要做的第一件事就是找出问题所在。

      如果它是安全的,并且唯一的目标是制作一个矩阵,你可以试试下面的代码。 一种解决方案是使用 pandas 来处理缺失值。 然后将 dataframe 转换为 numpy 矩阵。

      代码是

      import numpy as np
      import pandas as pd
      
      df = pd.DataFrame([[1, 1, 1, 1, 2], [2, 2, 2, 3], [3, 3, 3, 4], [13, 49, 13, 49], [10, 10, 2, 2],
                   [11, 1, 1, 1, 2], [22, 2, 2, 3], [33, 3, 3, 4], [133, 49, 13, 49], [100, 10, 2, 2],
                   [5, 1, 1, 1, 2], [32, 2, 2, 3], [322, 3, 3, 4], [13222, 49, 13, 49], [130, 10, 2, 2]])
      
      a = df.to_numpy()
      

      可以直接运行代码查看生成的矩阵。

      【讨论】:

      • 你怎么知道哪些元素被认为是“缺失”的?我认为这比帮助更危险,因为显然 OP 对原始数据进行了一些基本的虐待/误解,并且默默地将 NaN 添加到数据中并不能解决任何问题,而是隐藏了问题。
      • 放轻松。我只是提供一种基于数据生成 15x5 矩阵的方法。制作矩阵后,可以仔细处理带有 NaN 的行。我的解决方案没有隐藏它们,但指出了 NaN 的问题。
      【解决方案4】:

      Tl;博士。您的各个列表具有可变长度,因此迫使您的 NumPy 数组成为列表对象的一维数组,而不是整数/浮点数的二维数组

      只有当每个轴具有相同数量的元素时,才能定义 Numpy 数组。否则,您将得到一个 1D 对象数组。

      这就是您的阵列正在发生的事情。您有一个列表列表,其中包含可变数量的元素(一些 4 和一些 5)。这在转换过程中将其转换为 (15,) numpy 数组,其中数组有 15 个单独的列表对象。

      a = np.array([[1, 1, 1, 1, 2], [2, 2, 2, 3], [3, 3, 3, 4], [13, 49, 13, 49]
      ##           |______________|  |__________|
      ##                   |               |
      ##            5 length            4 length
      

      快速演示 -

      #Variable length sublists
      print(np.array([[1,2,3], [4,5]]))
      
      #Fixed length sublists
      print(np.array([[1,2,3], [4,5,6]]))
      
      array([list([1, 2, 3]), list([4, 5])], dtype=object)  #This is (2,)
      
      array([[1, 2, 3],                    #This is (2,3)
             [4, 5, 6]])
      
      1. 您可能想要做的是固定每个子列表中的元素数量。
      2. 或者您可能想在阵列上做一些填充

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-26
        • 1970-01-01
        • 2012-08-29
        • 2012-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多