Help us understand the problem. What is going on with this article?

Pythonのリスト要素からある値と最も近い値を取り出す

More than 3 years have passed since last update.

Pythonでリスト内からある値と最も近い値を取り出す際に少し手間取ったのでメモ.

失敗例

ネット上でnumpyのsearchsorted関数を使う方法を見たが, この関数はリストに値を挿入する際のインデックスを返却する関数なので, ある値ともっとも近い値のインデックスを返してくれるとは限らない.

実際に失敗した例

失敗例.py
# coding: utf-8

import numpy as np


def getNearestValue(list, num):

    # 昇順に挿入する際のインデックスを取得
    sortIdx = np.searchsorted(list, num, side='left')
    return list[sortIdx]


if __name__ == "__main__":

    list = [0, 0.5, 1]

    print(getNearestValue(list, 0.1))  # →0 OK
    print(getNearestValue(list, 0.4))  # →0 NG

上記コードのリスト内要素で0.4と最も近い値は0.5ですが, 0が返ってきています.

解決策

そこでsearchsorted関数で得られたインデックスの周辺要素から目的の値の差分を計算して, ある値ともっとも近い値を取り出す関数を実装しました.

追記: 2016/08/24
kochoryさんから大幅に効率化されたコードを教えて頂きました.
ある値とリスト内の要素の差分を計算し, その最小値のインデックスを求めることで実装しています.
ありがとうございます!

getNearestValue_sample2.py
# coding: utf-8

import numpy as np


def getNearestValue(list, num):
    """
    概要: リストからある値に最も近い値を返却する関数
    @param list: データ配列
    @param num: 対象値
    @return 対象値に最も近い値
    """

    # リスト要素と対象値の差分を計算し最小値のインデックスを取得
    idx = np.abs(np.asarray(list) - num).argmin()
    return list[idx]


if __name__ == "__main__":

    list = [0, 0.5, 1]

    print(getNearestValue(list, -0.1)) # →0
    print(getNearestValue(list, 0.1))  # →0
    print(getNearestValue(list, 0.4))  # →0.5
    print(getNearestValue(list, 0.5))  # →0.5
    print(getNearestValue(list, 0.6))  # →0.5
    print(getNearestValue(list, 0.8))  # →1
    print(getNearestValue(list, 1.2))  # →1
icchi_h
都内のメディア企業で働く高専出身エンジニア
https://icchi.me
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away