为扩展回归找到 y = 0 的 x 值
Find x-value where y = 0 for extended regression
我有以下数据集:
ID DATE VALUE
1 01-01-2020 98
1 02-01-2020 96
1 03-01-2020 94
2 01-01-2020 99
2 02-01-2020 90
2 05-01-2020 85
对于每个id,我想通过线性回归计算值达到0的日期。我成功地绘制了一条延长线,我可以通过以下代码直观地看到它达到 0 的点,但我没有成功提取确切的日期。
现在我的代码如下所示:
# convert date to ordinal
df['DATE_ord']=df['DATE'].map(dt.datetime.toordinal)
# Create plot with current values
ax = sns.regplot(data=df,x='DATE_ord',y='VALUE')
# Set x-axis values (ordinal dates)
date_range = np.arange(730000, 760000, 1000)
# Calculate extended values
slope, intercept, r_value, p_value, std_err = stats.linregress(x = df[
"DATE_ord"].values, y = df["VALUE"].values)
line = [slope*xi + intercept for xi in date_range]
plt.plot(date_range, line, label="Fitting Line", linewidth=1)
# Convert x-axis values back to date
ax.set_xlabel('date')
new_labels = [date.fromordinal(int(item)) for item in ax.get_xticks()]
ax.set_xticklabels(new_labels)
我现在需要找到 Y 值 (VALUE) 达到 0 的日期。我发现 或多或少想要达到相同的目的,但这不起作用,因为值在我的斜率与 x 轴的预测值不同,我不知道如何进行这项工作。我唯一能想到的就是用回归表达式计算它并填写数字,但我不确定如何以一种可以在我仍然需要创建的 for 循环中工作的方式来做到这一点遍历不同的 ID。
让我们尝试只用 pandas 来做这个,不要循环
加载示例数据
import pandas as pd
from io import StringIO
data = StringIO(
'''
ID DATE VALUE
1 01-01-2020 98
1 02-01-2020 96
1 03-01-2020 94
2 01-01-2020 99
2 02-01-2020 90
2 05-01-2020 85
''')
df = pd.read_csv(data, sep = '\s+')
df['DATE'] = pd.to_datetime(df['DATE'], dayfirst = True)
生成序数并计算每组的回归系数:
import datetime as dt
from scipy import stats
df['DATE_ord']=df['DATE'].map(dt.datetime.toordinal)
dfr = (df.groupby('ID').apply(lambda g: stats.linregress(x = g[
"DATE_ord"].values, y = g["VALUE"].values)[0:2])
.apply(pd.Series)
.rename(columns = {0 : 'slope', 1:'intercept'}))
dfr
我们明白了
slope intercept
ID
1 -2.000000 1.474948e+06
2 -3.076923 2.269096e+06
现在 'zero' 日期就是 0 = s * x + i 的解,即 x0 = -intercept/slope。我们计算序数并转换回日期
dfr['zd_ord'] = -dfr['intercept']/dfr['slope']
dfr['zd'] = dfr['zd_ord'].astype(int).map(dt.datetime.fromordinal)
得到
slope intercept zd_ord zd
ID
1 -2.000000 1.474948e+06 737474.00 2020-02-19
2 -3.076923 2.269096e+06 737456.35 2020-02-01
我有以下数据集:
ID DATE VALUE
1 01-01-2020 98
1 02-01-2020 96
1 03-01-2020 94
2 01-01-2020 99
2 02-01-2020 90
2 05-01-2020 85
对于每个id,我想通过线性回归计算值达到0的日期。我成功地绘制了一条延长线,我可以通过以下代码直观地看到它达到 0 的点,但我没有成功提取确切的日期。
现在我的代码如下所示:
# convert date to ordinal
df['DATE_ord']=df['DATE'].map(dt.datetime.toordinal)
# Create plot with current values
ax = sns.regplot(data=df,x='DATE_ord',y='VALUE')
# Set x-axis values (ordinal dates)
date_range = np.arange(730000, 760000, 1000)
# Calculate extended values
slope, intercept, r_value, p_value, std_err = stats.linregress(x = df[
"DATE_ord"].values, y = df["VALUE"].values)
line = [slope*xi + intercept for xi in date_range]
plt.plot(date_range, line, label="Fitting Line", linewidth=1)
# Convert x-axis values back to date
ax.set_xlabel('date')
new_labels = [date.fromordinal(int(item)) for item in ax.get_xticks()]
ax.set_xticklabels(new_labels)
我现在需要找到 Y 值 (VALUE) 达到 0 的日期。我发现
让我们尝试只用 pandas 来做这个,不要循环
加载示例数据
import pandas as pd
from io import StringIO
data = StringIO(
'''
ID DATE VALUE
1 01-01-2020 98
1 02-01-2020 96
1 03-01-2020 94
2 01-01-2020 99
2 02-01-2020 90
2 05-01-2020 85
''')
df = pd.read_csv(data, sep = '\s+')
df['DATE'] = pd.to_datetime(df['DATE'], dayfirst = True)
生成序数并计算每组的回归系数:
import datetime as dt
from scipy import stats
df['DATE_ord']=df['DATE'].map(dt.datetime.toordinal)
dfr = (df.groupby('ID').apply(lambda g: stats.linregress(x = g[
"DATE_ord"].values, y = g["VALUE"].values)[0:2])
.apply(pd.Series)
.rename(columns = {0 : 'slope', 1:'intercept'}))
dfr
我们明白了
slope intercept
ID
1 -2.000000 1.474948e+06
2 -3.076923 2.269096e+06
现在 'zero' 日期就是 0 = s * x + i 的解,即 x0 = -intercept/slope。我们计算序数并转换回日期
dfr['zd_ord'] = -dfr['intercept']/dfr['slope']
dfr['zd'] = dfr['zd_ord'].astype(int).map(dt.datetime.fromordinal)
得到
slope intercept zd_ord zd
ID
1 -2.000000 1.474948e+06 737474.00 2020-02-19
2 -3.076923 2.269096e+06 737456.35 2020-02-01