값 범위를 다른 값에 매핑
Python에서 한 범위 값을 다른 범위 값으로 변환하는 방법에 대한 아이디어를 찾고 있습니다. 저는 하드웨어 프로젝트를 진행 중이며 값 범위를 반환 할 수있는 센서에서 데이터를 읽고 있습니다. 그런 다음 해당 데이터를 사용하여 다른 값 범위가 필요한 액추에이터를 구동합니다.
예를 들어 센서가 1 ~ 512 범위의 값을 반환하고 액추에이터는 5 ~ 10 범위의 값에 의해 구동된다고 가정 해 보겠습니다. 값과 두 범위를 전달하고 값을 반환 할 수있는 함수를 원합니다. 두 번째 범위에 매핑됩니다. 이러한 함수의 이름이 지정되면 다음과 translate
같이 사용할 수 있습니다.
sensor_value = 256
actuator_value = translate(sensor_value, 1, 512, 5, 10)
이 예에서는가 가능한 입력 범위의 중간에 있기 때문에 출력 actuator_value
이 될 것으로 예상합니다 .7.5
sensor_value
한 가지 해결책은 다음과 같습니다.
def translate(value, leftMin, leftMax, rightMin, rightMax):
# Figure out how 'wide' each range is
leftSpan = leftMax - leftMin
rightSpan = rightMax - rightMin
# Convert the left range into a 0-1 range (float)
valueScaled = float(value - leftMin) / float(leftSpan)
# Convert the 0-1 range into a value in the right range.
return rightMin + (valueScaled * rightSpan)
가독성을 희생하면서 대수를 사용하여 더 효율적으로 만들 수 있습니다.
scipy.interpolate.interp1d 사용
scipy.interpolate
패키지를 사용 하여 이러한 변환을 수행 할 수도 있습니다 (SciPy에 대한 종속성이 마음에 들지 않는 경우).
>>> from scipy.interpolate import interp1d
>>> m = interp1d([1,512],[5,10])
>>> m(256)
array(7.4951076320939336)
또는 0 순위 scipy 배열에서 일반 float로 다시 변환하려면 :
>>> float(m(256))
7.4951076320939336
하나의 명령으로 여러 변환을 쉽게 수행 할 수도 있습니다.
>>> m([100,200,300])
array([ 5.96868885, 6.94716243, 7.92563601])
보너스로 [1,128]을 [1,10]에, [128,256]을 [10,90]에 그리고 [256,512]를 [90,100에 매핑하려는 경우 intance에 대해 한 범위에서 다른 범위로 불균일 한 매핑을 수행 할 수 있습니다. ] 다음과 같이 할 수 있습니다.
>>> m = interp1d([1,128,256,512],[1,10,90,100])
>>> float(m(400))
95.625
interp1d
부분 선형 보간 객체를 생성합니다 (함수처럼 호출 가능).
numpy.interp 사용
~ unutbu 에서 언급 했듯이은numpy.interp
(더 적은 종속성이있는) 옵션이기도합니다.
>>> from numpy import interp
>>> interp(256,[1,512],[5,10])
7.4951076320939336
이것은 실제로 함수를 반환하는 함수를 작성하는 클로저를 만드는 좋은 경우입니다. 이러한 값이 많을 것이므로 모든 값에 대해 이러한 값 범위와 계수를 계산하고 재 계산하는 데 가치가 거의 없습니다. 항상 해당 최소 / 최대 제한을 통과 할 때도 마찬가지입니다.
대신 다음을 시도하십시오.
def make_interpolater(left_min, left_max, right_min, right_max):
# Figure out how 'wide' each range is
leftSpan = left_max - left_min
rightSpan = right_max - right_min
# Compute the scale factor between left and right values
scaleFactor = float(rightSpan) / float(leftSpan)
# create interpolation function using pre-calculated scaleFactor
def interp_fn(value):
return right_min + (value-left_min)*scaleFactor
return interp_fn
이제 프로세서를 다음과 같이 작성할 수 있습니다.
# create function for doing interpolation of the desired
# ranges
scaler = make_interpolater(1, 512, 5, 10)
# receive list of raw values from sensor, assign to data_list
# now convert to scaled values using map
scaled_data = map(scaler, data_list)
# or a list comprehension, if you prefer
scaled_data = [scaler(x) for x in data_list]
def translate(sensor_val, in_from, in_to, out_from, out_to):
out_range = out_to - out_from
in_range = in_to - in_from
in_val = sensor_val - in_from
val=(float(in_val)/in_range)*out_range
out_val = out_from+val
return out_val
액추에이터 방향에 따라 0-300deg 각도를 원시 다이나믹 셀 값 0-1023 또는 1023-0에 매핑하기 위해 파이썬에서 동일한 것을 찾고있었습니다.
나는 결국 매우 단순하게되었다.
변수:
x:input value;
a,b:input range
c,d:output range
y:return value
함수:
def mapFromTo(x,a,b,c,d):
y=(x-a)/(b-a)*(d-c)+c
return y
용법:
dyn111.goal_position=mapFromTo(pos111,0,300,0,1024)
def maprange(a, b, s):
(a1, a2), (b1, b2) = a, b
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
a = [from_lower, from_upper]
b = [to_lower, to_upper]
https://rosettacode.org/wiki/Map_range#Python_ 에서 찾을 수 있습니다.
- 변환 된 값을 범위로 고정하지
a
않거나b
(외삽) - 또한 작동 할 때
from_lower > from_upper
또는to_lower > to_upper
ReferenceURL : https://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
'programing tip' 카테고리의 다른 글
ios5 ARC ARC에서 파일을 제외하는 컴파일러 플래그는 무엇입니까? (0) | 2021.01.05 |
---|---|
import pandas_datareader gives ImportError: cannot import name 'is_list_like' (0) | 2021.01.05 |
heroku open-지정된 앱 없음 (0) | 2021.01.05 |
Django가 Gunicorn으로 정적 파일을 제공하도록 만드는 방법은 무엇입니까? (0) | 2021.01.05 |
Java와 함께 Selenium2 (Webdriver)를 사용하여 IE 브라우저를 시작할 수 없음 (0) | 2021.01.05 |