Ad

How To Interpolate Data And Angles With PANDAS

I have a simple dataframe df that contains three columns:

  • Time: expressed in seconds
  • A: set of values that can vary between -inf to +inf
  • B: set of angles (degrees) which range between 0 and 359

Here is the dataframe

df = pd.DataFrame({'Time':[0,12,23,25,44,50], 'A':[5,7,9,8,11,6], 'B':[300,358,4,10,2,350]})

And it looks like this:

        Time  A   B
    0   0     5   300
    1   12    7   358
    2   23    9   4
    3   25    8   10
    4   44    11  2
    5   50    6   350

My idea is to interpolate the data from 0 to 50 seconds and I was able to achieve my goal using the following lines of code:

y  = pd.DataFrame({'Time':list(range(df['Time'].iloc[0], df['Time'].iloc[-1]))})
df = pd.merge(left=y, right=df, on='Time', how='left').interpolate()

Problem: even though column A is interpolated correctly, column B is wrong because the interpolation of an angle between 360 degrees is not performed! Here is an example:

    Time       A             B
12  12  7.000000    358.000000
13  13  7.181818    325.818182
14  14  7.363636    293.636364
15  15  7.545455    261.454545
16  16  7.727273    229.272727
17  17  7.909091    197.090909
18  18  8.090909    164.909091
19  19  8.272727    132.727273
20  20  8.454545    100.545455
21  21  8.636364    68.363636
22  22  8.818182    36.181818
23  23  9.000000    4.000000

Question: can you suggest me a smart and efficient way to solve this issue and being able to interpolate correctly the angles between 0/360 degrees?

Ad

Answer

You should be able to use the method described in this question for the angle column:

import numpy as np
import pandas as pd

df = pd.DataFrame({'Time':[0,12,23,25,44,50], 'A':[5,7,9,8,11,6], 'B':[300,358,4,10,2,350]})
df['B'] = np.rad2deg(np.unwrap(np.deg2rad(df['B'])))
y  = pd.DataFrame({'Time':list(range(df['Time'].iloc[0], df['Time'].iloc[-1]))})
df = pd.merge(left=y, right=df, on='Time', how='left').interpolate()
df['B'] %= 360
print(df)

Output:

    Time          A           B
0      0   5.000000  300.000000
1      1   5.166667  304.833333
2      2   5.333333  309.666667
3      3   5.500000  314.500000
4      4   5.666667  319.333333
5      5   5.833333  324.166667
6      6   6.000000  329.000000
7      7   6.166667  333.833333
8      8   6.333333  338.666667
9      9   6.500000  343.500000
10    10   6.666667  348.333333
11    11   6.833333  353.166667
12    12   7.000000  358.000000
13    13   7.181818  358.545455
14    14   7.363636  359.090909
15    15   7.545455  359.636364
16    16   7.727273    0.181818
17    17   7.909091    0.727273
18    18   8.090909    1.272727
19    19   8.272727    1.818182
20    20   8.454545    2.363636
21    21   8.636364    2.909091
22    22   8.818182    3.454545
23    23   9.000000    4.000000
24    24   8.500000    7.000000
25    25   8.000000   10.000000
26    26   8.157895    9.578947
27    27   8.315789    9.157895
28    28   8.473684    8.736842
29    29   8.631579    8.315789
30    30   8.789474    7.894737
31    31   8.947368    7.473684
32    32   9.105263    7.052632
33    33   9.263158    6.631579
34    34   9.421053    6.210526
35    35   9.578947    5.789474
36    36   9.736842    5.368421
37    37   9.894737    4.947368
38    38  10.052632    4.526316
39    39  10.210526    4.105263
40    40  10.368421    3.684211
41    41  10.526316    3.263158
42    42  10.684211    2.842105
43    43  10.842105    2.421053
44    44  11.000000    2.000000
45    45  11.000000    2.000000
46    46  11.000000    2.000000
47    47  11.000000    2.000000
48    48  11.000000    2.000000
49    49  11.000000    2.000000
Ad
source: stackoverflow.com
Ad