【问题标题】:numpy : How to convert an array type quicklynumpy : 如何快速转换数组类型
【发布时间】:2010-12-25 17:20:45
【问题描述】:

我发现 numpy 数组的 astype() 方法效率不高。我有一个数组包含 300万个Uint8点。将其乘以 3x3 矩阵需要 2 秒,但将结果从 uint16 转换为 uint8 需要另一秒。

更准确地说:

    print time.clock()
    imgarray = np.dot(imgarray,  M)/255
    print time.clock()
    imgarray = imgarray.clip(0, 255)
    print time.clock()
    imgarray = imgarray.astype('B')
    print time.clock()

点积和缩放需要 2 秒
削波需要 200 毫秒 类型转换需要 1 秒

考虑到其他操作所花费的时间,我预计astype 会更快。 有没有更快的方法来进行类型转换,或者我猜测类型转换不应该那么难时我错了?

编辑:目标是将最终的 8 位数组保存到文件中

【问题讨论】:

  • 为什么需要去 uint16 再回来?是否可以将M 作为 uint8 矩阵,那么就不需要转换了。
  • 点积的结果会超出uint8范围。我最初使用的是浮点 M 矩阵,并认为使用整数会给我一些改进,但事实并非如此。
  • 花费这么多时间的可能是访问所有内存位置。听起来很难修复。
  • 但是剪辑也是访问所有内存位置,但速度很快。希望剪辑不需要修改很多位置。用C做的类似操作没有这个内存带宽问题,所以我不买内存访问问题
  • 有意思,这三个操作分别需要0.2s、0.02s和0.01s。当然,我的机器似乎比你的机器快,但 astype() 操作肯定不会像乘法那样花费任何时间。

标签: python numpy


【解决方案1】:

当你使用imgarray = imgarray.astype('B') 时,你会得到一个数组的副本,转换为指定的类型。这需要额外的内存分配,即使您立即翻转 imgarray 以指向新分配的数组。

如果您使用imgarray.view('uint8'),那么您将获得数组的视图。这使用相同的数据,只是它被解释为uint8 而不是imgarray.dtype。 (np.dot 返回一个uint32 数组,所以在np.dot 之后,imgarray 的类型是uint32。)

然而,使用view 的问题在于,一个 32 位整数被视为 4 个 8 位整数,而我们只关心最后 8 位中的值。所以我们需要跳到每第 4 个 8 位整数。我们可以通过切片来做到这一点:

imgarray.view('uint8')[:,::4]

IPython 的 %timeit 命令显示以这种方式执行操作可以显着加快速度:

In [37]: %timeit imgarray2 = imgarray.astype('B')
10000 loops, best of 3: 107 us per loop

In [39]: %timeit imgarray3 = imgarray.view('B')[:,::4]
100000 loops, best of 3: 3.64 us per loop

【讨论】:

猜你喜欢
  • 2016-12-29
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 2020-03-16
  • 2011-03-25
  • 2011-05-22
相关资源
最近更新 更多