데이터가있는 배열이 있습니다.
X Y
3 50
5 60
9 120
11 130
18 90
20 150
데이터는 전적으로 비선형입니다. X는 정렬되도록 보장됩니다.
이제 주어진 값에 대해 숫자 사이에 선형 보간을 원합니다 (예 : 3 => 50, 4 => 55, 5 => 60). 쌍 선형 보간이 더 좋을 것이지만 기대치를 낮게 유지하고 있습니다.
답변
이 스크립트는 같은 작업을 수행합니다 (약간 조금 더).
암호
function myInterpolation(x, y, value) {
if(value > Math.max.apply(Math, x) || value < Math.min.apply(Math, x)) {
throw "value can't be interpolated !!";
return;
}
var check = 0, index;
for(var i = 0, iLen = x.length; i < iLen; i++) {
if(x[i][0] == value) {
return y[i][0];
} else {
if(x[i][0] < value && ((x[i][0] - check) < (value - check))) {
check = x[i][0];
index = i;
}
}
}
var xValue, yValue, xDiff, yDiff, xInt;
yValue = y[index][0];
xDiff = x[index+1][0] - check;
yDiff = y[index+1][0] - yValue;
xInt = value - check;
return (xInt * (yDiff / xDiff)) + yValue;
}
설명
스크립트 시작 부분에는 약간의 오류 처리가 있습니다. 그런 다음 입력 값과 비교하여 가장 낮은 첫 번째 항목을 찾습니다. 일단 발견되면 수학을 수행하고 결과를 제시합니다.
노트
선택한 값이 20과 같으면 스크립트는 수식이 산출하는 위치로 150을 반환합니다 #DIV/0
.
스크린 샷
공식
모든 값을 고려하려면 다음 공식을 사용하십시오.
=IF(
ISNA(
MATCH(C2,A2:A7,0)),
FORECAST(
$C$2,
OFFSET(B$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1),
OFFSET(A$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1)),
INDEX(
B2:B7,
MATCH(C2,A2:A7,0)
,0)
)
copy / paste
=IF(ISNA(MATCH(C2, A2:A7, 0)), FORECAST($C$2,OFFSET(B$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1),OFFSET(A$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1)), INDEX(B2:B7, MATCH(C2, A2:A7, 0), 0))
예
도구> 스크립트 편집기에서 스크립트를 추가하고 저장 버튼을 누릅니다 (인증 필요 없음).
예제 파일을 만들었습니다. Google 스프레드 시트에서 일정 범위의 데이터를 보간하는 방법
답변
나는 그것을하는 방법을 찾았습니다-더 좋은 방법이있을 수 있지만 이것이 내가 생각해 낸 것입니다.
데이터가 A1 : B10이고 $ C $ 1에 다음과 같은 키가 있다고 가정합니다.
=FORECAST($C$1,
OFFSET(B$1,MATCH($C$1,A$1:A$10,1)-1,0,2,1),
OFFSET(A$1,MATCH($C$1,A$1:A$10,1)-1,0,2,1))
상세히:
FORECAST는 선형 보간을 수행하지만 직선을 가정합니다. 따라서 원하는 값을 포함하는 두 개의 값을 찾아야합니다.
따라서 MATCH를 사용하여 찾고있는 것과 같거나 높은 첫 번째 숫자를 찾습니다.
FORECAST는 데이터 범위를 예상하므로 OFFSET을 사용하여 데이터 범위에 대한 참조를 만듭니다. MATCH는 하나의 인덱스이므로 먼저 빼야합니다. 우리는 1과 2의 범위를 만듭니다. 이 값은 검색 값인 $ C $ 1을 포함합니다.
답변
이것은 Jacob Jan Tuinstra의 스크립트를 약간 수정 하여 배열이나 값을 세 번째 인수로 사용할 수 있으므로 보간 된 함수를 한 번에 여러 곳에서 계산할 수 있습니다. 유일한 차이점은 처음에 몇 줄이 추가 된 것입니다. 이것은 거의 모든 사용자 정의 함수를 배열을 허용하는 사용자 정의 함수로 전환하는 빠른 방법입니다.
function myInterpolation(x, y, value) {
if (value.map) {
return value.map(function(v) {
return myInterpolation(x, y, v);
});
}
// the rest stays the same
if (value > Math.max.apply(Math, x) || value < Math.min.apply(Math, x)) {
throw "value can't be interpolated !!";
return;
}
var check = 0, index;
for(var i = 0, iLen = x.length; i < iLen; i++) {
if(x[i][0] == value) {
return y[i][0];
} else {
if(x[i][0] < value && ((x[i][0] - check) < (value - check))) {
check = x[i][0];
index = i;
}
}
}
var xValue, yValue, xDiff, yDiff, xInt;
yValue = y[index][0];
xDiff = x[index+1][0] - check;
yDiff = y[index+1][0] - yValue;
xInt = value - check;
return (xInt * (yDiff / xDiff)) + yValue;
}