Home > database >  Linear interpolation of two time series to merge data in numpy
Linear interpolation of two time series to merge data in numpy

Time:09-30

I'm processing joystick data. There are two time series, one for the joystick's X motion and another for its Y motion. The two data sets have different time stamps. In the end, I hope to use matplotlib to plot a parametric 2D graph of the joystick data (where time is implicit, and the X and Y motion make up the points on the graph). However, before this end goal, I have to "merge" the two time series. For convenience, I'm going to assume that joystick motion is linear between timestamps.

I've coded something that can complete this (see below), but it seems needlessly complex. I'm hoping to find a more simplistic approach to accomplish this linear interpolation if possible.

import numpy as np
import matplotlib.pyplot as plt

# Example data
X = np.array([[0.98092103,   1013],
              [1.01400101,    375],
              [1.0561214,   -8484],
              [1.06982589, -17181],
              [1.09453125, -16965]])

Y = np.array([[0.98092103,    534],
             [1.00847602,   1690],
             [1.0392499,   -5327],
             [1.06982589, -27921],
             [1.10026598, -28915]])

data = []
# keep track of which index was used last
current_indices = [-1, -1]
# make ordered list of all timestamps between both data sets, no repeats
all_timestamps = sorted(set(X[:, 0]).union(set(Y[:, 0])))
for ts in all_timestamps:
    # for each dimension (X & Y), index where timestamp exists, if timestamp exists. Else None 
    ts_indices = tuple(indx[0] if len(indx := np.where(Z[:, 0] == ts)[0]) > 0 else None
                        for Z in (X, Y))
    # Out of range timesteps assumed to be zero
    ts_vals = [0, 0]
    for variable_indx, (current_z_indx, Z) in enumerate(zip(ts_indices, (X, Y))):
        last_index_used = current_indices[variable_indx]
        if current_z_indx is not None:
            # If timestep is present, get value
            current_indices[variable_indx] = current_z_indx
            ts_vals[variable_indx] = Z[current_z_indx, 1]
        elif last_index_used not in (-1, len(Z[:, 0]) - 1):
            # If timestep within range of data, linearly interpolate
            t0, z0 = Z[last_index_used, :]
            t1, z1 = Z[last_index_used   1, :]
            ts_vals[variable_indx] = z0   (z1 - z0) * (ts - t0) / (t1 - t0)
    data.append([ts, *ts_vals])
merged_data = np.array(data)

plt.plot(merged_data[:,1],merged_data[:,2])
plt.show()

CodePudding user response:

You are looking for np.interp to simplify the linear interpolation.

Following your example:

import numpy as np
import matplotlib.pyplot as plt

# Example data
X = np.array([[0.98092103,   1013],
              [1.01400101,    375],
              [1.0561214,   -8484],
              [1.06982589, -17181],
              [1.09453125, -16965]])

Y = np.array([[0.98092103,    534],
             [1.00847602,   1690],
             [1.0392499,   -5327],
             [1.06982589, -27921],
             [1.10026598, -28915]])

#extract all timestamps
all_timestamps = sorted(set(X[:, 0]).union(set(Y[:, 0])))

#linear interpolation
valuesX = np.interp(all_timestamps, X[:,0], X[:,1])
valuesY = np.interp(all_timestamps, Y[:,0], Y[:,1])

#plotting
plt.plot(valuesX, valuesY)
plt.show()
  • Related