提问人:Rezwan Khan 提问时间:11/12/2023 更新时间:11/12/2023 访问量:52
缩放或将 numpy 数组的每个条目映射到另一个值范围
Scaling or, mapping each entry of numpy array to another range of values
问:
我正在尝试将强化学习连续动作值映射到实际输出。range(-1.0,1.0)
假设我有 numpy 操作数组。数组的值可以是 和 。actions = np.array([-1., 0.2, -0.3, 0.5])
actions.min = -1.
actions.max = 1.
现在,我需要将每个条目映射到单独的范围,例如
- actions[0] 映射到 range(-0.4 , 1.54)
- 操作[1] 映射到 range(1.4 , 1.54)
- actions[2] 映射到 range(-2.4 , 2.0)
- actions[3] 映射到 range(-1.54 , 0.4)
因此,映射操作mapped_actions = np.array([-0.4, 1.484, -0.86, -0.085])
我目前的解决方案如下:
import numpy as np
actions = np.array([-1., 0.2, -0.3, 0.5])
mapped_low_high = np.array([[-0.4, 1.54], [1.4, 1.54],[-2.4, 2.], [-1.54, 0.4]])
mapped_actions = np.zeros_like(actions)
for i in range(actions.shape[0]):
mapped_actions[i] = np.interp(actions[i], (-1., 1.), mapped_low_high[i])
有没有更好的方法可以将操作数组映射到mapped_actions?
答:
2赞
jared
11/12/2023
#1
使用 numpy 数组循环很慢。编写一个可以同时对整个数组进行操作的矢量化函数会更快。由于我们知道给定的数组将始终介于 -1 和 1 之间,并且我们有一个新范围的数组,因此代码是一个从一个范围映射到另一个范围的简单函数。一般技术是将原始数据映射到 ,然后将其映射到 。[0, 1]
[a, b]
import numpy as np
actions = np.array([-1., 0.2, -0.3, 0.5])
mapped_low_high = np.array([[-0.4, 1.54],
[1.4, 1.54],
[-2.4, 2.],
[-1.54, 0.4]])
def remap(arr, mappings):
out = arr.copy()
a, b = mappings.T
# remap out to [0,1]
# assumes arr is [-1,1]
out += 1.
out /= 2.
# remap out to [a,b]
out *= b - a
out += a
return out
remapped = remap(actions, mapped_low_high) # array([-0.4 , 1.484, -0.86 , -0.085])
评论
2赞
AJ Biffl
11/12/2023
把它放在一行中可能更容易,return a + (b-a)*(arr + 1)/2
0赞
jared
11/12/2023
是的,但我选择把它分成多行,这样我就可以更清楚地解释这个过程。
0赞
Rezwan Khan
11/12/2023
我暗暗地希望能得到一些神奇的功能。但答案是有效的。我会等待 24 小时,然后接受这个作为答案numpy
1赞
aazizzailani
11/12/2023
#2
直接使用该函数映射整个数组,而无需使用循环。np.interp
actions
import numpy as np
actions = np.array([-1., 0.2, -0.3, 0.5])
mapped_low_high = np.array([[-0.4, 1.54], [1.4, 1.54], [-2.4, 2.], [-1.54, 0.4]])
# Use np.interp directly on the entire array
mapped_actions = np.interp(actions, (-1., 1.), mapped_low_high.T)
# Transpose the results to obtain the desired shape
mapped_actions = mapped_actions.T
print(mapped_actions)
通过在整个数组上使用,您可以避免使用循环,并以更简洁的方法获得相同的结果。np.interp
评论
0赞
Rezwan Khan
11/12/2023
我希望有这个功能。np.intep
0赞
AJ Biffl
11/13/2023
仔细观察后,这实际上接近标记,但不幸的是,我找不到一种方法来按照所需的方式对其进行矢量化。该行确实生成了所需结果的列表,但未作为 @jared 的答案进行矢量化[np.interp(actions[i], (-1,1), mapped_low_high[i]) for i in range(4)]
评论