python数组切片效率_python-为什么使用numpy.save从数组保存切片会更慢,具体取决于切片的方向?...

简短答案

只有roix数组是c_contiguous.因此,从内存到CPU的总线传输比非连续数据传输更快(由于总线将数据按块移动并缓存)

通过使其成为C连续的np.save(file,np.asarray(a,order =’C’)),您可以进行一些改进(roiz约为5%,roiy约为40%)

更多说明

剖析

您应该使用timeit来计时表演而不是自定义方法.

我已经为您展示了这些示例:

在一个单元格中,我们得到:

import os

import numpy as np

import time

import matplotlib.pyplot as plt

# take a slice of the data

def slice_data(roi):

dic = {}

data = np.zeros((512,512,256))

dic['data'] = np.squeeze( data[roi[0]:roi[1]+1, roi[2]:roi[3]+1, roi[4]:roi[5]+1] )

return dic

# save slices if the data

def save_slices(roi, save=False):

var = 'data'

for i in range(0,6):

# iterate to simulate a time series of data

a = slice_data(roi)[var]

var_dir = 'save_test/'

if not os.path.exists(var_dir): os.makedirs(var_dir)

file = var_dir + '{0:04d}{1}'.format(i,'.npy')

if save is True:

np.save(file, a)

## define slices

roix=[256, 256, 0, 512, 0, 256] # yz plane slice

roiy=[0, 512, 256, 256, 0, 256] # xz plane slice

roiz=[0, 512, 0, 512, 128, 128] # xy plane slice

在其他方面:

%%timeit -n 100

save_slices(roix) # 19.8 ms ± 285 ?s per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit -n 100

save_slices(roiy) # 20.5 ms ± 948 ?s per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit -n 100

save_slices(roiz) # 20 ms ± 345 ?s per loop (mean ± std. dev. of 7 runs, 100 loops each)

随着保存

%%timeit -n 10 -r 3

save_slices(roix, True) # 32.7 ms ± 2.31 ms per loop (mean ± std. dev. of 3 runs, 10 loops each)

%%timeit -n 10 -r 3

save_slices(roiy, True) # 101 ms ± 2.61 ms per loop (mean ± std. dev. of 3 runs, 10 loops each)

%%timeit -n 10 -r 3

save_slices(roix, True) # 1.9 s ± 21.1 ms per loop (mean ± std. dev. of 3 runs, 10 loops each)

因此,正如您已经注意到的,在不节省资源的情况下,性能是相同的!

让我们进入np.save()方法

NP保存方法

np.save负责io流,并调用write_array方法.对于C_contigous数组,这确实非常快. (快速访问内存)

让我们验证这个假设:

np.squeeze( np.zeros((512,512,256))[roix[0]:roix[1]+1, roix[2]:roix[3]+1, roix[4]:roix[5]+1] ).flags.c_contiguous # returns True

np.squeeze( np.zeros((512,512,256))[roiy[0]:roiy[1]+1, roiy[2]:roiy[3]+1, roiy[4]:roiy[5]+1] ).flags.c_contiguous # returns False

np.squeeze( np.zeros((512,512,256))[roiz[0]:roiz[1]+1, roiz[2]:roiz[3]+1, roiz[4]:roiz[5]+1] ).flags.c_contiguous # returns False

因此,这可以解释roix和roiy / roiz之间的区别.

roiy和roiz之间差异的潜在解释.数据传输使程序变慢

在那之后,我只能作个假设,roiz似乎比roiy更加分散. write_array方法要花费很多时间.

我现在无法自己对此进行测试,但是可以使用linux中的perf命令来验证这一部分. (要查看使用的时间总线数量,例如高速缓存未命中的数量).

如果我必须做一个大胆的猜测,我会说由于数据不连续而导致高速缓存丢失率很高.因此,将数据从RAM传输到CPU确实减慢了该过程.

处理存储的其他方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值