1

たとえば、時系列と値系列を含む、同じ長さの2つの1D配列があります。

t = linspace(0, 5, 5) # [0, 1.25, 2.5, 3.75, 5]
x = array(range(10, 25)) # [10, 11, 12, 13, 14]

たとえば、異なるサンプリングポイントを使用してx配列をリサンプリングする必要があります(開始ポイントと終了ポイントは同じですが、要素の数はいくつでもかまいません)。

r = linspace(0, 5, 4) # [ 0, 1.667, 3.333, 5]
x2 = resample(t, x, r) # [10, 11, 12, 14]

つまり、rの各時点はtの2つの時点の間に配置され、tの2つの下の点のインデックスを見つけたいと思います。インデックスの配列から、xの相対点を取得することができます。

ループのない、おそらくscipyの演算子を使用したベクトルベースのソリューションが必要です。scipyの関数を使用する場合に適しています。

編集:これが私が必要とすることを行うコードですが、より短く、より速く、ベクトルベースのソリューションの方が良いでしょう。私はそれを見つけることができませんでした(しかし試みるまで)。

def resample(t, r):
    i, j, k = 0, 1, 0
    s = []
    while j < len(t):
        if t[i] <= r[k] < t[j]:
            s.append(i)
            k += 1
        else:
            i += 1
            j += 1
    s.append(len(t) - 1)
    return array(s)
4

3 に答える 3

1

interp1dの関数を使用して、引数をにscipy.interpolate指定してみてください。配列の使用:kindzero

>>> from scipy.interpolate import interp1d
>>> f = interp1d(t,x,kind="zero")
>>> f(r)
array((10, 11, 12, 13))

「resampled」配列の最後の要素は13であり、質問で要求した14ではなく、f(5.001) = 14(*)であることに注意してください。「リサンプリングされた」配列が元の配列のポイントの1つと一致する場合は常に、補間関数は不連続になります。

bounds_error=False(*)の範囲外でリサンプリングする場合は、interp1d呼び出しでキーワード引数を指定する必要がありますt

于 2013-01-30T23:11:50.917 に答える
1

次の2つの小さな関数の2つ目は、必要な処理を実行できます。

def resample_up(t, x, r) :
    return x[np.argmax(r[:, None] <= t, axis=1)]

def resample_down(t, x, r) :
    return x[::-1][np.argmax(r[:, None] >= t[::-1], axis=1)]

>>> resample_up(t, x, r)
array([10, 12, 13, 14])
>>> resample_down(t, x, r)
array([10, 11, 12, 14])

何が起こっているのか理解するのが難しい場合は、次のことが役立つ場合があります。

>>> r[:, None] <= t
array([[ True,  True,  True,  True,  True],
       [False, False,  True,  True,  True],
       [False, False, False,  True,  True],
       [False, False, False, False,  True]], dtype=bool)
>>> r[:, None] >= t[::-1]
array([[False, False, False, False,  True],
       [False, False, False,  True,  True],
       [False, False,  True,  True,  True],
       [ True,  True,  True,  True,  True]], dtype=bool)

次に、すべての行でnp.argmax最初に出現するインデックスを返します。True

編集ITは、1行のコードよりも短くするのは困難ですが、大きな配列の場合、インデックスの検索がループの初期に発生することはないため、パフォーマンスが低下します。したがって、非常に大きな配列の場合、Pythonループを使用して配列をスキャンする方が高速になる可能性があります。小さいものの場合、それはしません:

In [2]: %timeit resample_up(t, x, r)
100000 loops, best of 3: 7.32 us per loop

In [3]: %timeit resample_down(t, x, r)
100000 loops, best of 3: 8.44 us per loop

In [4]: %timeit resample(t, x, r) # modified version of the OP's taking also x
100000 loops, best of 3: 13.7 us per loop
于 2013-01-30T23:55:58.327 に答える
1

numpy.interpは、高速で単純な区分的線形補間器です。

from __future__ import division
import numpy as np

t = np.linspace(0, 5, 5)  # [0, 1.25, 2.5, 3.75, 5]
x = np.array(range(10, 15))  # [10, 11, 12, 13, 14]
r = np.linspace(0, 5, 4)  # [ 0, 1.667, 3.333, 5]

print "np.interp:", np.interp( r, t, x )
    # [ 10.    11.33  12.67  14.  ]
xint = np.arange( len(t) )
print "r to int:", np.interp( r, t, xint ).astype(int)
    # [0 1 2 4]
于 2013-02-02T14:26:28.160 に答える