Python 迭代3D numpy数组并计算每个序列的百分比变化
我在迭代、广播和一般的循环代码制作方面有很大的知识差距 我有一组大小为(2000,10200)的序列。我想获取每个(10200)序列,并将所有10行除以该序列的第一行,以获得仅相对于单个窗口的百分比变化 此外,我只想对总共200个元素中的前100个元素执行除法操作 使用传统for循环的伪代码:Python 迭代3D numpy数组并计算每个序列的百分比变化,python,arrays,numpy,Python,Arrays,Numpy,我在迭代、广播和一般的循环代码制作方面有很大的知识差距 我有一组大小为(2000,10200)的序列。我想获取每个(10200)序列,并将所有10行除以该序列的第一行,以获得仅相对于单个窗口的百分比变化 此外,我只想对总共200个元素中的前100个元素执行除法操作 使用传统for循环的伪代码: #Loop over each of the 2000 sequences #Loop over each of the 10 rows #Divide each row (first 100 eleme
#Loop over each of the 2000 sequences
#Loop over each of the 10 rows
#Divide each row (first 100 elements) by the the first row-1 (first 100 elements) and save
这是我的尝试,虽然它不起作用,而且可能不是正确的方法。非常感谢对代码的任何解释
for sequence in data:
for row in data[0][row]:
data[0][row] = data[0][row][0:99] / data[0][0][0:99] -1
设置让我们看一个较小的示例:
data = np.arange(72).reshape(3, 4, 6) + 10
data
array([[[10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33]],
[[34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45],
[46, 47, 48, 49, 50, 51],
[52, 53, 54, 55, 56, 57]],
[[58, 59, 60, 61, 62, 63],
[64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75],
[76, 77, 78, 79, 80, 81]]])
解决方案
首先确定要划分最后一个维度中的多少个维度
half_last_dim = data.shape[-1] // 2
其次,使用长度为1的数组对第二维度进行切片,以保持维度并启用广播
data[:, :, :half_last_dim] / data[:, [0], :half_last_dim]
array([[[ 1. , 1. , 1. ],
[ 1.6 , 1.54545455, 1.5 ],
[ 2.2 , 2.09090909, 2. ],
[ 2.8 , 2.63636364, 2.5 ]],
[[ 1. , 1. , 1. ],
[ 1.17647059, 1.17142857, 1.16666667],
[ 1.35294118, 1.34285714, 1.33333333],
[ 1.52941176, 1.51428571, 1.5 ]],
[[ 1. , 1. , 1. ],
[ 1.10344828, 1.10169492, 1.1 ],
[ 1.20689655, 1.20338983, 1.2 ],
[ 1.31034483, 1.30508475, 1.3 ]]])
分配回数据
使
数据
类型浮动
# Only necessary because my example started with integers.
data = data.astype(float)
data[:, :, :half_last_dim] /= data[:, [0], :half_last_dim]
data.round(2) # rounded for pretty printing
array([[[ 1. , 1. , 1. , 13. , 14. , 15. ],
[ 1.6 , 1.55, 1.5 , 19. , 20. , 21. ],
[ 2.2 , 2.09, 2. , 25. , 26. , 27. ],
[ 2.8 , 2.64, 2.5 , 31. , 32. , 33. ]],
[[ 1. , 1. , 1. , 37. , 38. , 39. ],
[ 1.18, 1.17, 1.17, 43. , 44. , 45. ],
[ 1.35, 1.34, 1.33, 49. , 50. , 51. ],
[ 1.53, 1.51, 1.5 , 55. , 56. , 57. ]],
[[ 1. , 1. , 1. , 61. , 62. , 63. ],
[ 1.1 , 1.1 , 1.1 , 67. , 68. , 69. ],
[ 1.21, 1.2 , 1.2 , 73. , 74. , 75. ],
[ 1.31, 1.31, 1.3 , 79. , 80. , 81. ]]])
更多解释
为了获得正确的广播,我们希望我们正在广播的东西与所有维度相匹配,除了我们目标的维度。对于这个维度,我们需要长度
1
data.shape
(3, 4, 6)
data[:, [0], :].shape
(3, 1, 6)
设置让我们看一个较小的示例:
data = np.arange(72).reshape(3, 4, 6) + 10
data
array([[[10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33]],
[[34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45],
[46, 47, 48, 49, 50, 51],
[52, 53, 54, 55, 56, 57]],
[[58, 59, 60, 61, 62, 63],
[64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75],
[76, 77, 78, 79, 80, 81]]])
解决方案
首先确定要划分最后一个维度中的多少个维度
half_last_dim = data.shape[-1] // 2
其次,使用长度为1的数组对第二维度进行切片,以保持维度并启用广播
data[:, :, :half_last_dim] / data[:, [0], :half_last_dim]
array([[[ 1. , 1. , 1. ],
[ 1.6 , 1.54545455, 1.5 ],
[ 2.2 , 2.09090909, 2. ],
[ 2.8 , 2.63636364, 2.5 ]],
[[ 1. , 1. , 1. ],
[ 1.17647059, 1.17142857, 1.16666667],
[ 1.35294118, 1.34285714, 1.33333333],
[ 1.52941176, 1.51428571, 1.5 ]],
[[ 1. , 1. , 1. ],
[ 1.10344828, 1.10169492, 1.1 ],
[ 1.20689655, 1.20338983, 1.2 ],
[ 1.31034483, 1.30508475, 1.3 ]]])
分配回数据
使
数据
类型浮动
# Only necessary because my example started with integers.
data = data.astype(float)
data[:, :, :half_last_dim] /= data[:, [0], :half_last_dim]
data.round(2) # rounded for pretty printing
array([[[ 1. , 1. , 1. , 13. , 14. , 15. ],
[ 1.6 , 1.55, 1.5 , 19. , 20. , 21. ],
[ 2.2 , 2.09, 2. , 25. , 26. , 27. ],
[ 2.8 , 2.64, 2.5 , 31. , 32. , 33. ]],
[[ 1. , 1. , 1. , 37. , 38. , 39. ],
[ 1.18, 1.17, 1.17, 43. , 44. , 45. ],
[ 1.35, 1.34, 1.33, 49. , 50. , 51. ],
[ 1.53, 1.51, 1.5 , 55. , 56. , 57. ]],
[[ 1. , 1. , 1. , 61. , 62. , 63. ],
[ 1.1 , 1.1 , 1.1 , 67. , 68. , 69. ],
[ 1.21, 1.2 , 1.2 , 73. , 74. , 75. ],
[ 1.31, 1.31, 1.3 , 79. , 80. , 81. ]]])
更多解释
为了获得正确的广播,我们希望我们正在广播的东西与所有维度相匹配,除了我们目标的维度。对于这个维度,我们需要长度
1
data.shape
(3, 4, 6)
data[:, [0], :].shape
(3, 1, 6)
太棒了,你真是太棒了。这是一行非常优雅的代码。我会做进一步的阅读,但是我能问一下为什么添加-1不适用于这个用例吗?数据[:,:,:98]/=(数据[:,[0],:98]-1)这是就地操作如何工作的问题。您编写的是获取
(dataXtrain[:,[0],:98]-1)
的结果,并使用dataXtrain[:,:,:98]/(dataXtrain[:,[0],:98]-1)
覆盖dataXtrain[:,:,:98]-1的值。我想你的意思是dataXtrain[:,:,:98]=dataXtrain[:,:,:98]/dataXtrain[:,[0],:98]-1
或dataXtrain[:,:,:98]/=dataXtrain[:,[0],:98];dataXtrain[:,[0],:98]-=1
是的,我正要写这个,我只是把它改成了单独的操作。再次感谢你的帮助!太棒了,你真是太棒了。这是一行非常优雅的代码。我会做进一步的阅读,但是我能问一下为什么添加-1不适用于这个用例吗?数据[:,:,:98]/=(数据[:,[0],:98]-1)这是就地操作如何工作的问题。您编写的是获取(dataXtrain[:,[0],:98]-1)
的结果,并使用dataXtrain[:,:,:98]/(dataXtrain[:,[0],:98]-1)
覆盖dataXtrain[:,:,:98]-1的值。我想你的意思是dataXtrain[:,:,:98]=dataXtrain[:,:,:98]/dataXtrain[:,[0],:98]-1
或dataXtrain[:,:,:98]/=dataXtrain[:,[0],:98];dataXtrain[:,[0],:98]-=1
是的,我正要写这个,我只是把它改成了单独的操作。再次感谢你的帮助!