83
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-24

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
83
77
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?