大家好,欢迎来到IT知识分享网。
在NumPy中,数组在内存中的存储方式是由其shape和strides属性共同决定的。其中,shape描述了数组的维度和每个维度上的大小,strides描述了在每个维度上相邻元素之间的跨度,也就是在内存中相邻元素之间的字节数。
具体来说,如果一个形状为(n1, n2, …, nk)的数组在内存中以行优先(C顺序)存储,那么其strides为(n2 * … * nk * itemsize, n3 * … * nk * itemsize, …, nk * itemsize, itemsize),其中itemsize为每个元素所占用的字节数。这意味着在访问数组的第(i1, i2, …, ik)个元素时,需要跨越i1 * n2 * … * nk * itemsize + i2 * n3 * … * nk * itemsize + … + ik * itemsize个字节,才能到达该元素所在的内存地址。
例如,对于一个形状为(2, 3, 4)的三维数组,假设每个元素占用4个字节,那么其strides为(48, 16, 4)。这意味着在访问数组的第(i, j, k)个元素时,需要跨越i * 48 + j * 16 + k * 4个字节,才能到达该元素所在的内存地址。
理解数组的strides可以帮助我们更好地理解数组在内存中的存储方式和访问方式,从而更好地管理内存和提高计算效率。例如,当我们对一个数组进行切片或重塑操作时,可以利用strides来避免数据的复制,从而节省内存和提高效率。
假设我们有一个二维数组a,其形状为(3, 4),数据类型为int32,内存地址从0x1000开始,每个元素占用4个字节,则其strides为(16, 4)。
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.int32) print(a.strides) # 输出(16, 4)
假设我们现在想获取a的第二列,可以使用切片操作,生成一个新的一维数组b。如果我们直接对a[:, 1]进行切片,则会生成一个新的数组并复制数据,这会消耗额外的内存。但是,我们可以利用strides来避免数据的复制,从而节省内存。
b = a[:, 1] # 直接对a的第二列进行切片 print(b) # 输出[ 2 6 10] print(b.strides) # 输出(16,),说明b每隔16个字节(即一个整数),才会有一个新的元素
可以看到,切片生成的新数组b的strides为(16,),说明每隔16个字节(即一个整数),才会有一个新的元素。这个跨度和a的strides中的第一个值相同,因为b和a在第一个维度上的大小相同。这意味着在访问b中的元素时,只需要跳过相应的字节数即可,而不需要复制数据。
类似地,我们可以利用strides来重塑一个数组。假设我们想把数组a重塑成一个形状为(2, 6)的二维数组。如果我们直接对a进行重塑操作,则会生成一个新的数组并复制数据。但是,我们可以利用strides来避免数据的复制,从而节省内存。
c = a.reshape((2, 6)) # 对a进行重塑操作 print(c) # 输出[[ 1 2 3 4 5 6] # [ 7 8 9 10 11 12]] print(c.strides) # 输出(24, 4),说明c每隔24个字节(即6个整数),才会有一个新的元素
可以看到,重塑生成的新数组c的strides为(24, 4),说明每隔24个字节(即6个整数),才会有一个新的元素。这个跨度和a的strides中的第一个值相同,因为c和a在第一个维度上的大小相同。这意味着在访问c中的元素时,只需要跳过相应的字节数即可,而不需要复制数据。
另外一个例子是对数组进行转置。假设我们有一个二维数组a,其形状为(3, 4),数据类型为int32,内存地址从0x1000开始,每个元素占用4个字节,则其strides为(16, 4)。如果我们想把a进行转置,可以使用transpose方法,也可以使用切片操作生成一个新的数组b。同样,我们可以利用strides来避免数据的复制,从而节省内存。
b = a.T # 对a进行转置操作 print(b) # 输出[[ 1 5 9] # [ 2 6 10] # [ 3 7 11] # [ 4 8 12]] print(b.strides) # 输出(4, 16),说明b每隔4个字节(即一个整数),才会有一个新的元素
可以看到,转置生成的新数组b的strides为(4, 16),说明每隔4个字节(即一个整数),才会有一个新的元素。这个跨度和a的strides中的第二个值相同,因为b和a在第二个维度上的大小相同。这意味着在访问b中的元素时,只需要跳过相应的字节数即可,而不需要复制数据。
通过这些例子,我们可以看到,利用strides可以实现数据共享,避免数据的复制,从而节省内存。这在处理大规模数据时尤为重要,可以让我们在不增加计算机内存的情况下,处理更大的数据集。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/97346.html