pythonpandasdataframelinear-regressioncoefficients

How to train a linear regression for each pandas dataframe row and generate the slope


I have created the following pandas dataframe:

import numpy as np
import pandas as pd
    
ds = {'col1' : [11,22,33,24,15,6,7,68,79,10,161,12,113,147,115]}
df = pd.DataFrame(data=ds)

predFeature = []

for i in range(len(df)):
    predFeature.append(0)
    predFeature[i] = predFeature[i-1]+1

df['predFeature'] = predFeature

                
arrayTarget = []
arrayPred = []
target = np.array(df['col1'])
predFeature = np.array(df['predFeature'])

for i in range(len(df)):

    arrayTarget.append(target[i-4:i])
    arrayPred.append(predFeature[i-4:i])
        
df['arrayTarget'] = arrayTarget
df['arrayPred'] = arrayPred

Which looks like this:

    col1  predFeature          arrayTarget         arrayPred
0     11            1                   []                []
1     22            2                   []                []
2     33            3                   []                []
3     24            4                   []                []
4     15            5     [11, 22, 33, 24]      [1, 2, 3, 4]
5      6            6     [22, 33, 24, 15]      [2, 3, 4, 5]
6      7            7      [33, 24, 15, 6]      [3, 4, 5, 6]
7     68            8       [24, 15, 6, 7]      [4, 5, 6, 7]
8     79            9       [15, 6, 7, 68]      [5, 6, 7, 8]
9     10           10       [6, 7, 68, 79]      [6, 7, 8, 9]
10   161           11      [7, 68, 79, 10]     [7, 8, 9, 10]
11    12           12    [68, 79, 10, 161]    [8, 9, 10, 11]
12   113           13    [79, 10, 161, 12]   [9, 10, 11, 12]
13   147           14   [10, 161, 12, 113]  [10, 11, 12, 13]
14   115           15  [161, 12, 113, 147]  [11, 12, 13, 14]

I need to generate a new column called slope, which corresponds to the coefficient of a linear regression trained for each row and for which:

For example:

And so on.

Can anyone help me, please?


Solution

  • You can define a function that uses sklearn.linear_model.LinearRegression and apply it on axis=1. Won't be very efficient if your dataframe is too large.

    import numpy as np
    import pandas as pd
    from sklearn.linear_model import LinearRegression
    
    
    lr = LinearRegression()
    
    
    def calculate_slope(x, y):
        if len(x) < 1:
            return np.nan
        lr.fit(x.reshape(-1, 1), y)
        return lr.coef_[0]
    
    
    df["slope"] = df.apply(
        lambda x: calculate_slope(x["arrayTarget"], x["arrayPred"]), axis=1
    )
    
        col1  predFeature          arrayTarget         arrayPred     slope
    0     11            1                   []                []       NaN
    1     22            2                   []                []       NaN
    2     33            3                   []                []       NaN
    3     24            4                   []                []       NaN
    4     15            5     [11, 22, 33, 24]      [1, 2, 3, 4]  0.102041
    5      6            6     [22, 33, 24, 15]      [2, 3, 4, 5] -0.090909
    6      7            7      [33, 24, 15, 6]      [3, 4, 5, 6] -0.111111
    7     68            8       [24, 15, 6, 7]      [4, 5, 6, 7] -0.142857
    8     79            9       [15, 6, 7, 68]      [5, 6, 7, 8]  0.030418
    9     10           10       [6, 7, 68, 79]      [6, 7, 8, 9]  0.030769
    10   161           11      [7, 68, 79, 10]     [7, 8, 9, 10]  0.002331
    11    12           12    [68, 79, 10, 161]    [8, 9, 10, 11]  0.009048
    12   113           13    [79, 10, 161, 12]   [9, 10, 11, 12] -0.001640
    13   147           14   [10, 161, 12, 113]  [10, 11, 12, 13]  0.004698
    14   115           15  [161, 12, 113, 147]  [11, 12, 13, 14]  0.002174