我在迭代,广播以及通常制作循环代码方面存在巨大差距。
我有一组大小的序列(2000,10,200)。我想采用每个(10,200)序列并将所有10行除以该序列的第一行,以获得相对于单个窗口的百分比变化。
此外,我只想对200总数的前100个元素执行除法运算。
使用传统for循环的伪代码:
#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
答案 0 :(得分:2)
<强>设置强>
让我们看一个较小的例子:
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
其次,使用长度为一的数组切割第二维以保持维度并启用广播
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 ]]])
回到data
使data
类型为float
# 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. ]]])
更多解释
See Broadcasting Rules
为了使广播正确,我们希望我们广播的内容与所有尺寸的尺寸相匹配,除了我们定位的尺寸。对于该维度,我们需要长度1
data.shape
(3, 4, 6)
data[:, [0], :].shape
(3, 1, 6)