😺

pandas で線形フィットを行う かつ 対応する値を計算する

2024/03/20に公開

pandas で線形フィットを行う かつ 対応する値を計算する

コード

import pandas as pd
import numpy as np
import time

# 仮のデータフレームを作成
start_x = 10
start_y = 100
num     = 150000
df = pd.DataFrame({
    'x': np.arange(start_x, start_x+num),
    'y': np.arange(start_y, start_y+num) + np.random.randn(num)
})

# 'x'列と'y'列に対して1次の多項式フィットを行う
coeff = np.polyfit(df['x'], df['y'], 1)

# 線形フィットの計算値 (やり方1)
start = time.time()
df["fit"]  = df['x'].apply(vfunc)
diff1 = time.time() - start

# 線形フィットの計算値 (やり方2)
vfunc = np.vectorize(lambda x: coeff[0] * x + coeff[1])
start = time.time()
df["fit2"]  = vfunc(df['x'])
diff2 = time.time() - start

# 線形フィットの計算値 (やり方3)
start = time.time()
df["fit3"]  = np.polyval(coeff, df['x'])
diff3 = time.time() - start

df["error"] = (df['fit'] - df['y']).abs()
df["rate%"] = (df['error'] / df["y"]) * 100
print(df)
print(diff1)
print(diff2)
print(diff3)

説明

np.polyfit で線形フィットする。戻り値で ax + b(a, b) の部分を返す。

np.vectorize で普通の関数をベクター関数化する。ここでは lambda 関数を渡す。

やり方1

dataframe の apply で引数で渡した関数 (ここでは vfunc) を指定した列に適用する。

df["fit"] が 線形フィットした値になる。

やり方2

vfunc(df['x'])df['x'] の各列に対して線形フィットした値を求める。
df["fit2"] が 線形フィットした値になる。

やり方3 (最速)

np.polyval で引数に dataframe の列を渡す。

出力例

             x              y            fit           fit2           fit3     error     rate%
0           10     100.291546     100.002049     100.002049     100.002049  0.289497  0.288655
1           11     102.088520     101.002049     101.002049     101.002049  1.086471  1.064244
2           12     101.339129     102.002049     102.002049     102.002049  0.662919  0.654159
3           13     104.631109     103.002049     103.002049     103.002049  1.629060  1.556956
4           14     103.962152     104.002049     104.002049     104.002049  0.039896  0.038376
...        ...            ...            ...            ...            ...       ...       ...
149995  150005  150095.398152  150095.004077  150095.004077  150095.004077  0.394075  0.000263
149996  150006  150096.283725  150096.004077  150096.004077  150096.004077  0.279648  0.000186
149997  150007  150095.972876  150097.004077  150097.004077  150097.004077  1.031201  0.000687
149998  150008  150098.102642  150098.004077  150098.004077  150098.004077  0.098565  0.000066
149999  150009  150100.863748  150099.004077  150099.004077  150099.004077  1.859670  0.001239

[150000 rows x 7 columns]
0.9963786602020264
0.04494190216064453
0.0010008811950683594

参考リンク

Discussion