はじめに
Pythonで1次元の numpy.ndarray
型の時間波形を扱っていて、処理の途中にスライスでダウンサンプリングしたいと思ったのですが、すぐに手実装ができず Chat GPT を使って実装したので、備忘録として記録しておきます。
コード
下記がコードです。2つの関数があります。
downsample
は確実にインデックスが含まれる場合に使える関数downsample_searchsorted
は最も近いインデックスを取得してくれる関数- こちらの方が最も近いインデックスを探すために、データ数が多いと遅くなりがちのようです。
import timeit
import numpy as np
def downsample(t: np.ndarray, data: np.ndarray, t_downsample: np.ndarray) -> np.ndarray:
"""
Perform downsampling on time series data using slicing.
Parameters
----------
t : numpy.ndarray
Original time axis.
data : numpy.ndarray
Original data corresponding to the time axis.
t_downsample : numpy.ndarray
New time axis for downsampling.
Returns
-------
numpy.ndarray
Downsampled data.
"""
indices = ((t_downsample - t[0]) / (t[1] - t[0])).astype(int)
extracted_data = data[indices]
return extracted_data
def downsample_searchsorted(
t: np.ndarray, data: np.ndarray, t_downsample: np.ndarray
) -> np.ndarray:
"""
Perform downsampling on time series data using np.searchsorted.
Parameters
----------
t : numpy.ndarray
Original time axis.
data : numpy.ndarray
Original data corresponding to the time axis.
t_downsample : numpy.ndarray
New time axis for downsampling.
Returns
-------
numpy.ndarray
Downsampled data.
"""
closest_indices = np.searchsorted(t, t_downsample)
extracted_data = data[closest_indices]
return extracted_data
# Generate original data
t_original = np.arange(0, 100000, 1)
data_original = t_original * 10
# Specify the range and step size for the new time axis for downsampling
start_value = 0
end_value = 10000
step_size = 2
t_downsample = np.arange(start_value, end_value, step_size)
# Measure the time taken by each function
time_downsample = timeit.timeit(
lambda: downsample(t_original, data_original, t_downsample),
number=100,
)
time_searchsorted = timeit.timeit(
lambda: downsample_searchsorted(t_original, data_original, t_downsample),
number=100,
)
print(f"t_original : {t_original}")
print(f"data_original : {data_original}")
print(f"t_downsample : {t_downsample}")
print(f"data_downsample : {downsample(t_original, data_original, t_downsample)}")
# t_original : [ 0 1 2 ... 99997 99998 99999]
# data_original : [ 0 10 20 ... 999970 999980 999990]
# t_downsample : [ 0 2 4 ... 9994 9996 9998]
# data_downsample : [ 0 20 40 ... 99940 99960 99980]
# Output the results
print(
f"Time taken by downsample function: {time_downsample:.6f} seconds"
) # 0.003711 seconds
print(
f"Time taken by downsample_searchsorted function: {time_searchsorted:.6f} seconds"
) # 0.032072 seconds
おわりに
備忘録として残しました。
コメント