【问题标题】:Removing length 1 dimensions in arrays删除数组中的长度 1 维
【发布时间】:2015-11-17 15:11:39
【问题描述】:

我是 Python 的真正初学者,我的 ndarray 经常出现问题。 我对括号很困惑(是否有任何在 Python 中任何地方使用括号的示意图综合?)。我总是最终得到具有许多维度的数组。 现在我有这个:

>>> values
Out[1]: 
array([[[ array([[ 4.23156519, -0.93539198],
       [ 3.50074853, -1.67043386],
       [ 4.64192393, -1.03918172],
       [ 4.52056725,  0.2561267 ],
       [ 3.36400016,  0.26435125],
       [ 3.82025672,  1.16503286]])]]], dtype=object)

从这里,我怎样才能减少尺寸?我只想要一个 6x2 阵列。我尝试了np.reshape,但由于values 的当前形状是 (1,1,1),我无法直接将数组重塑为 6x2 的形状。

对于这个愚蠢的问题,我很抱歉,我正在寻找一个通用且示意性的答案,它可以解释我如何从更高维度传递到更低维度,反之亦然。

这是我创建array 的方式。 valuesclustered_points

indices=[] # initialize indices
clustered_points=[] # initialize array containing points in different sub-arrays=clusters
for k in range(len(mu)):
    a=r[:,k]
    index=[t for t in range(len(a)) if a[t] == 1]
    indices.append(index)
    clustered_points.append(data[indices[k]])
clustered_points=np.reshape(clustered_points,(len(clustered_points),1,1))

【问题讨论】:

  • 我可以用values.reshape(6,2) 轻松地重塑它...你得到什么错误?你也试过values.astype(np.float).reshape(6,2) 吗?
  • 第一种情况:ValueError: total size of new array must be unchanged第二种情况:ValueError: setting an array element with a sequence
  • 数组中有一个数组。外层有 dtype 对象。
  • 你是怎么想出那个代码的?您不想要的几个长度为 1 的维度,您在 reshape 调用中显式添加

标签: python arrays numpy dimensions brackets


【解决方案1】:

要制作一个与您的初始显示相匹配的数组,我必须特别注意将一个数组嵌入另一个数组:

In [402]: x=np.array([[ 4.23156519, -0.93539198],
       [ 3.50074853, -1.67043386],
       [ 4.64192393, -1.03918172],
       [ 4.52056725,  0.2561267 ],
       [ 3.36400016,  0.26435125],
       [ 3.82025672,  1.16503286]])
In [403]: a=array([[[None]]],dtype=object)
In [404]: a[0,0,0]=x
In [405]: a
Out[405]: 
array([[[ array([[ 4.23156519, -0.93539198],
       [ 3.50074853, -1.67043386],
       [ 4.64192393, -1.03918172],
       [ 4.52056725,  0.2561267 ],
       [ 3.36400016,  0.26435125],
       [ 3.82025672,  1.16503286]])]]], dtype=object)

In [406]: a.shape
Out[406]: (1, 1, 1)
In [407]: a[0,0,0].shape
Out[407]: (6, 2)

只需从显示器上进行剪切粘贴即可生成形状为(1,1,1,6,2) 的不同阵列。那没有内部array 标记。无论哪种方式,a[0,0,0] 都会给出内部 (6,2) 数组。

reshapesqueeze 作用于 (1,1,1,6,2) 数组,但不适用于嵌套在 (1,1,1) 中的 (6,2)。您需要了解其中的区别。


(编辑)

要运行您的“我是如何做到的”剪辑,我必须对输入进行一些猜测(这几乎值得一票否决)。

我会猜测一些输入:

In [420]: mu=np.arange(3); r=np.ones((4,3));data=np.ones(5)
In [421]: %paste
indices=[] # initialize indices
clustered_points=[] # initialize array containing points in different sub-arrays=clusters
for k in range(len(mu)):
    a=r[:,k]
    index=[t for t in range(len(a)) if a[t] == 1]
    indices.append(index)
    clustered_points.append(data[indices[k]])

## -- End pasted text --
In [422]: clustered_points
Out[422]: 
[array([ 1.,  1.,  1.,  1.]),
 array([ 1.,  1.,  1.,  1.]),
 array([ 1.,  1.,  1.,  1.])]

cluster_points 是一个包含多个一维数组的列表。

我可以的

np.reshape(clustered_points,(12,1,1))
np.reshape(clustered_points,(3,4,1,1))

虽然我认为最好先做np.array(clustered_points),甚至可以检查它的形状。

自从

np.reshape(clustered_points,(len(clustered_points),1,1))

假设有效,那么clustered_points 必须是n 单元素数组的列表。但是这个重塑应该产生一个(n,1,1) 数组,而不是你的(1,1,1,...) 数组。

所以编辑没有帮助。

===========================

我正在寻找一个通用且示意性的答案,它可以解释我如何从更高维度传递到更低维度,反之亦然。

第一步是清楚,对你自己和其他人来说,你的数组的结构是什么。这包括知道shapedtype。如果dtype 不是简单的数字,请注意元素的结构(例如数组中的对象)。

可以使用索引、[0]squeeze 删除奇异维度(值 1)。 reshape 也会移除维度(或添加维度),但您必须注意元素的总数。如果旧形状有 12 个元素,那么新形状也必须有 12 个。但是 reshape 不会跨越 dtype 边界。

【讨论】:

    【解决方案2】:

    我想你在找numpy.squeeze

    #!/usr/bin/env python
    
    import numpy
    a = [[[[[ 4.23156519, -0.93539198],
            [ 3.50074853, -1.67043386],
            [ 4.64192393, -1.03918172],
            [ 4.52056725,  0.2561267 ],
            [ 3.36400016,  0.26435125],
            [ 3.82025672,  1.16503286]]]]]
    a = numpy.array(a)
    print("a.shape=%s" % str(a.shape))
    b = numpy.squeeze(a)
    print("b.shape=%s" % str(b.shape))
    

    给予

    a.shape=(1, 1, 1, 6, 2)
    b.shape=(6, 2)
    

    【讨论】:

      【解决方案3】:

      根本问题可能是,你是如何创建这个数组的?

      不能以与np.ndarrays 相同的方式操作 python list 对象。一般来说,一旦创建了最终列表,就可以将其转换为 numpy 数组:

      values = []
      # fill values with values.append(...)
      # ...
      values = np.asarray(values)
      

      要查找数组的形状,您可以使用A.shapenp.shape(A)。要删除长度为 1 的维度,最好的方法是使用 squeeze 方法作为 A.squeeze()np.squeeze(A),即:

      >>> values.squeeze()
      array([[4.23156519, -0.93539198],
            [3.50074853, -1.67043386],
            [4.64192393, -1.03918172],
            [4.52056725, 0.2561267],
            [3.36400016, 0.26435125],
            [3.82025672, 1.16503286]], dtype=object)
      

      如果你的values数组真的如你所说,那么使用reshape也应该没问题

      >>> values.reshape(6,2)
      array([[4.23156519, -0.93539198],
             [3.50074853, -1.67043386],
             [4.64192393, -1.03918172],
             [4.52056725, 0.2561267],
             [3.36400016, 0.26435125],
             [3.82025672, 1.16503286]], dtype=object)
      

      如果您在尝试 reshape values 时遇到错误,它是否可能实际上是 list 而不是 array

      【讨论】:

      • 也可以。我说array 因为这是我在Pycharm 调试器上读到的接近变量的内容。我在问题中添加了创建元素的方式
      • @KillingBambi,不。您正在创建一个list,它不是numpy 数据结构,并且行为不同。我已经更新了我的答案。尝试将您的 list 重铸为 array
      【解决方案4】:

      如果您想创建 6x2 数组,那么只需这样做:

      A = array([[4.23156519, -0.93539198],
                 [3.50074853, -1.67043386],
                 [4.64192393, -1.03918172],
                 [4.52056725, 0.2561267],
                 [3.36400016, 0.26435125],
                 [3.82025672, 1.16503286]], dtype=object)
      

      如果你想减少你的数组:

      A = array([[[ array([[ 4.23156519, -0.93539198],
                 [ 3.50074853, -1.67043386],
                 [ 4.64192393, -1.03918172],
                 [ 4.52056725,  0.2561267 ],
                 [ 3.36400016,  0.26435125],
                 [ 3.82025672,  1.16503286]])]]], dtype=object)
      

      其实是1x1x1x6x2数组,你可以通过A[0][0][0]得到6x2

      【讨论】:

        猜你喜欢
        • 2018-02-27
        • 2021-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-25
        相关资源
        最近更新 更多