0

リストがあります:

values = [[6.23234121,6.23246575],[1.352672,1.352689],[6.3245,123.35323,2.3]]

このリストを調べて、たとえば0.01内にあるすべてのアイテムを同じリスト内の他の要素に削除する方法は何ですか。

delを使用して特定のリストのセットに対してそれを行う方法は知っていますが、値にn個のリストがあり、各リストにn個の要素がある場合に一般的にしたいと考えています。

私がしたいのは、このリストに対して何らかの操作を実行することです

values = [[6.23234121,6.23246575],[1.352672,1.352689],[6.3245,123.35323,2.3]]

この出力を取得します

new_values = [[6.23234121],[1.352672],[6.3245,123.35323,2.3]]
4

1 に答える 1

1

単一のリストに対してこれを行う関数を作成します。

>>> compact([6.23234121,6.23246575], tol=.01)
[6.23234121]

その後、ネストされた構造で動作させることができます[compact(l) for l in lst]

これらの各メソッドは、リスト内でそれに近いものを持たない最初の要素を保持します。@DSM の例では、[0, 0.005, 0.01, 0.015, 0.02]それらはすべて返され[0, 0.0.15]ます (または、に切り替え>た場合>=[0, 0.01, 0.02])。何か違うものが必要な場合は、それが何であるかをより慎重に定義する必要があります。


まず、デビッドの答えに似た簡単なアプローチ。これは O(n^2) です:

def compact(lst, tol):
    new = []
    for el in lst:
        if all(abs(el - x) > tol for x in new):
            new.append(el)
    return compact

3 要素リストでは、これはまったく問題ありません。ただし、300 万要素のリストでそれを実行したい場合は、それでは不十分です。別のことを試してみましょう:

import collections
import math

def compact(lst, tol):
    round_digits = -math.log10(tol) - 1
    seen = collections.defaultdict(set)
    new = []
    for el in lst:
        rounded = round(seen, round_digits)
        if all(abs(el - x) > tol for x in seen[rounded]):
            seen[rounded].add(el)
            new.append(el)
    return new

もしあなたtolがなら0.01、それround_digitsは 1です。次に が表示されたら、それを に丸め、インデックスで検索します。インデックスには、検索している数値に含まれる可能性のあるすべての数値が含まれている必要があります。次に、これらの数値までの距離を確認する必要がありますが、リスト全体ではなく、そのインデックス ビンにあるごく少数の数値についてのみ確認する必要があります。6.23234121seen6.26.232465756.2tol

このアプローチは O(nk) です。ここで、k は 1 つのビン内に収まる要素の平均数です。k << n の場合にのみ役立ちます (通常はそうですが、使用している数値の分布に依存しますtol)。また、他のアプローチよりもおそらく 2 倍以上のメモリを使用することに注意してください。これは、非常に大きなリストでは問題になる可能性があります。


もう 1 つのオプションは、最初にリストをソートすることです。その場合は、前後の要素を調べて競合を確認するだけで済みます。

于 2013-02-07T00:32:16.743 に答える