【问题标题】:Slice numpy array to make it desired shaped切片 numpy 数组以使其具有所需的形状
【发布时间】:2016-09-21 16:37:45
【问题描述】:

令人惊讶的是,在互联网上找不到答案。我有一个 n 维 numpy 数组。例如:二维 np 数组:

array([['34.5500000', '36.9000000', '37.3200000', '37.6700000'],
       ['41.7900000', '44.8000000', '48.2600000', '46.1800000'],
       ['36.1200000', '37.1500000', '39.3100000', '38.1000000'],
       ['82.1000000', '82.0900000', '76.0200000', '77.7000000'],
       ['48.0100000', '51.2500000', '51.1700000', '52.5000000', '55.2500000'],
       ['39.7500000', '39.5000000', '36.8100000', '37.2500000']], dtype=object)

如您所见,第 5 行由 5 个元素组成,我想让第 5 行消失,使用如下代码:

np.slice(MyArray, [6,4]) 

[6,4] 是一个形状。我真的不想迭代抛出的尺寸并切割它们。我尝试了resize 方法,但它什么也没返回!

【问题讨论】:

  • 其实你的数组只是一个列表向量。
  • @wim 但是所有 np n 维数组都是 ...n-1 次...列表的向量的向量,不是吗?
  • 这个数组的形状是什么? MyArray.shape?
  • np.array 未实现为列表列表。显示看起来像它,但在内部,numpy 不是这样工作的。但在这种情况下,您确实有一个列表数组。

标签: python arrays numpy


【解决方案1】:

这不是二维数组。它是一个一维数组,其元素是对象,在这种情况下,一些 4 元素列表和一个 5 元素列表。这个列表包含字符串。

In [577]: np.array([['34.5500000', '36.9000000', '37.3200000', '37.6700000'],
     ...:        ['41.7900000', '44.8000000', '48.2600000', '46.1800000'],
     ...:        ['36.1200000', '37.1500000', '39.3100000', '38.1000000'],
     ...:        ['82.1000000', '82.0900000', '76.0200000', '77.7000000'],
     ...:        ['48.0100000', '51.2500000', '51.1700000', '52.5000000', '55.25
     ...: 00000'],
     ...:        ['39.7500000', '39.5000000', '36.8100000', '37.2500000']], dtyp
     ...: e=object)
Out[577]: 
array([['34.5500000', '36.9000000', '37.3200000', '37.6700000'],
       ['41.7900000', '44.8000000', '48.2600000', '46.1800000'],
       ['36.1200000', '37.1500000', '39.3100000', '38.1000000'],
       ['82.1000000', '82.0900000', '76.0200000', '77.7000000'],
       ['48.0100000', '51.2500000', '51.1700000', '52.5000000', '55.2500000'],
       ['39.7500000', '39.5000000', '36.8100000', '37.2500000']], dtype=object)
In [578]: MyArray=_
In [579]: MyArray.shape
Out[579]: (6,)
In [580]: MyArray[0]
Out[580]: ['34.5500000', '36.9000000', '37.3200000', '37.6700000']
In [581]: MyArray[5]
Out[581]: ['39.7500000', '39.5000000', '36.8100000', '37.2500000']
In [582]: MyArray[4]
Out[582]: ['48.0100000', '51.2500000', '51.1700000', '52.5000000', '55.2500000']
In [583]: 

slice这个你需要迭代数组的元素

In [584]: [d[:4] for d in MyArray]
Out[584]: 
[['34.5500000', '36.9000000', '37.3200000', '37.6700000'],
 ['41.7900000', '44.8000000', '48.2600000', '46.1800000'],
 ['36.1200000', '37.1500000', '39.3100000', '38.1000000'],
 ['82.1000000', '82.0900000', '76.0200000', '77.7000000'],
 ['48.0100000', '51.2500000', '51.1700000', '52.5000000'],
 ['39.7500000', '39.5000000', '36.8100000', '37.2500000']]

现在所有子列表的长度相同,np.array 将创建一个二维数组:

In [585]: np.array(_)
Out[585]: 
array([['34.5500000', '36.9000000', '37.3200000', '37.6700000'],
       ['41.7900000', '44.8000000', '48.2600000', '46.1800000'],
       ['36.1200000', '37.1500000', '39.3100000', '38.1000000'],
       ['82.1000000', '82.0900000', '76.0200000', '77.7000000'],
       ['48.0100000', '51.2500000', '51.1700000', '52.5000000'],
       ['39.7500000', '39.5000000', '36.8100000', '37.2500000']], 
      dtype='<U10')

还是字符串

In [586]: np.array(__,dtype=float)
Out[586]: 
array([[ 34.55,  36.9 ,  37.32,  37.67],
       [ 41.79,  44.8 ,  48.26,  46.18],
       [ 36.12,  37.15,  39.31,  38.1 ],
       [ 82.1 ,  82.09,  76.02,  77.7 ],
       [ 48.01,  51.25,  51.17,  52.5 ],
       [ 39.75,  39.5 ,  36.81,  37.25]])

【讨论】:

  • 这不是我想要看到的,但这很好,谢谢。最后一个输出的元素是字符串吗?这个事实是否限制了我使用 numpy 功能?
  • 最后一个表达式产生一个二维浮点数组。
  • 对不起,我的错,之前和你的评论混淆了)
【解决方案2】:

这是一个几乎*矢量化的方法 -

def slice_2Dobject_arr(arr,out_shape):
    lens = np.array(map(len,arr))
    id_arr = np.ones(lens.sum(),dtype=int)
    id_arr[lens[:-1].cumsum()] = -lens[:-1]+1
    mask = id_arr.cumsum()<=out_shape[1]
    vals = np.concatenate(arr)
    return vals[mask].reshape(-1,out_shape[1])[:out_shape[0]]

*:几乎是因为在开始时使用map 来获取输入数组中列表的长度,这似乎不是向量化操作。但是,从计算上来说应该可以忽略不计。

示例运行 -

In [92]: arr
Out[92]: array([[3, 4, 5, 3], [3, 7, 8], [4, 9, 6, 4, 2], [3, 9, 4]], dtype=object)

In [93]: slice_2Dobject_arr(arr,(4,3))
Out[93]: 
array([[3, 4, 5],
       [3, 7, 8],
       [4, 9, 6],
       [3, 9, 4]])

In [94]: slice_2Dobject_arr(arr,(3,3))
Out[94]: 
array([[3, 4, 5],
       [3, 7, 8],
       [4, 9, 6]])

In [95]: slice_2Dobject_arr(arr,(3,2))
Out[95]: 
array([[3, 4],
       [3, 7],
       [4, 9]])

【讨论】:

  • 太酷了,我马上试试。与以前的答案相比,有什么好处吗??
  • @VladislavLadenkov 好吧,似乎另一个答案使用了loop comprehension。因此,当您在该输入数组中有大量列表时,可能会在性能上看到好处。
  • 此解决方案将数组展平,并使用掩码切掉不需要的东西,最后重塑。如果速度(v.易读性)很重要,您必须对实际大小的数组进行速度测试。
  • @hpaulj 确实存在一些设置开销,所以正如我所说,我们需要该数组中的大量列表才能看到任何潜在的好处。
猜你喜欢
  • 2017-03-12
  • 2015-10-03
  • 2018-01-14
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多