Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python scipy单变量样条线在打印时始终返回线性ish样条线_Python_Matplotlib_Scipy_Spline_Timeserieschart - Fatal编程技术网

Python scipy单变量样条线在打印时始终返回线性ish样条线

Python scipy单变量样条线在打印时始终返回线性ish样条线,python,matplotlib,scipy,spline,timeserieschart,Python,Matplotlib,Scipy,Spline,Timeserieschart,我有以下一组数据(pandas.DataFrame),我想使用scipy.interpolate.UnivariateSpline来拟合。让我们调用datadata Date 2018-04-02 09:00:00 16249 2018-04-02 10:00:00 45473 2018-04-02 11:00:00 32050 2018-04-02 12:00:00 35898 2018-04-02 13:00:00 21577 2018-04-02 1

我有以下一组数据(
pandas.DataFrame
),我想使用
scipy.interpolate.UnivariateSpline
来拟合。让我们调用data
data

Date
2018-04-02 09:00:00     16249
2018-04-02 10:00:00     45473
2018-04-02 11:00:00     32050
2018-04-02 12:00:00     35898
2018-04-02 13:00:00     21577
2018-04-02 14:00:00     30545
2018-04-02 15:00:00     60925
2018-04-02 16:00:00     47124
2018-04-03 09:00:00     18534
2018-04-03 10:00:00     36064
2018-04-03 11:00:00     32387
2018-04-03 12:00:00     15903
2018-04-03 13:00:00     22291
2018-04-03 14:00:00     26367
2018-04-03 15:00:00     66269
2018-04-03 16:00:00     38478
2018-04-04 09:00:00     15803
2018-04-04 10:00:00     22511
2018-04-04 11:00:00     33123
2018-04-04 12:00:00     21000
2018-04-04 13:00:00     23132
2018-04-04 14:00:00     39270
2018-04-04 15:00:00    102544
2018-04-04 16:00:00    143421
2018-04-04 17:00:00       200
2018-04-05 09:00:00     23377
2018-04-05 10:00:00     52089
2018-04-05 11:00:00     99298
2018-04-05 12:00:00     24627
2018-04-05 13:00:00     33467
2018-04-05 14:00:00     26498
2018-04-05 15:00:00    114794
2018-04-05 16:00:00     44904
2018-04-06 09:00:00     12180
2018-04-06 10:00:00     41658
2018-04-06 11:00:00     64066
2018-04-06 12:00:00     12517
2018-04-06 13:00:00     12610
2018-04-06 14:00:00     43544
2018-04-06 15:00:00     65533
2018-04-06 16:00:00    123885
2018-04-09 09:00:00     13425
2018-04-09 10:00:00     38354
2018-04-09 11:00:00     59491
2018-04-09 12:00:00     21402
2018-04-09 13:00:00     24550
2018-04-09 14:00:00     25189
2018-04-09 15:00:00     67751
2018-04-09 16:00:00     16071
2018-04-10 09:00:00     35587
2018-04-10 10:00:00     58667
2018-04-10 11:00:00     41831
2018-04-10 12:00:00     35196
2018-04-10 13:00:00     22611
2018-04-10 14:00:00     23070
2018-04-10 15:00:00     40819
2018-04-10 16:00:00     20337
2018-04-11 09:00:00      7962
2018-04-11 10:00:00     23982
2018-04-11 11:00:00     21794
2018-04-11 12:00:00     16835
2018-04-11 13:00:00     16821
2018-04-11 14:00:00     13270
2018-04-11 15:00:00     34954
2018-04-11 16:00:00     15772
2018-04-12 09:00:00      8587
2018-04-12 10:00:00     47950
2018-04-12 11:00:00     24742
2018-04-12 12:00:00     16743
2018-04-12 13:00:00     21917
2018-04-12 14:00:00     43272
2018-04-12 15:00:00     50630
2018-04-12 16:00:00    104656
2018-04-13 09:00:00     15282
2018-04-13 10:00:00     30304
2018-04-13 11:00:00     65737
2018-04-13 12:00:00     17467
2018-04-13 13:00:00     10439
2018-04-13 14:00:00     19836
2018-04-13 15:00:00     52051
2018-04-13 16:00:00     99462
到目前为止,我所做的是:

import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate as interp

x = [i for i in range(1, data.size+1)]  # this gives x as an array from 1 to 82.

spl = interp.UnivariateSpline(x, data.values, s=0.5)
xx = np.linspace(min(x), max(x), 1000)  # 1000 is an arbitrary number here.
plt.plot(x, data.values, 'bo')
plt.plot(xx, spl(xx), 'r')
plt.show()

# the plot is below and it seems to be very linear and does not look like a cubic spline at all. Cubic Spline is the default.

当我针对
x
运行
spl
时,其他变量保持不变,即:

plt.plot(x, spl(x), 'r')
我得到以下信息:

唯一不同的是y轴的顶部为14000,这似乎意味着之前的图显示了一定程度的曲率。(还是没有?)

我不确定我错过了什么,但我显然错过了什么。我对python中的
spline
fitting仍然是个新手

你能告诉我如何正确拟合上面的时间序列吗

编辑

根据你的评论,我想添加另一个情节,希望能更好地解释我自己。我并不是说它是线性的,但我找不到更好的词了。举例来说

xxx = [10,20,40,60,80]
plt(x, data.values, 'bo')
plt(xx, sp(xx), 'r')

plt.show()
我认为下面的情节在我看来是相当线性的。我猜,也许我的问题应该是,
scipy.UnivariateSpline
到底是如何工作的

它是否仅显示在我们提供的点处评估的值的曲线图(例如,对于该曲线图,它是
xxx


我期待一个更平滑的曲线图。问题的答案显示了我所期待的情节;它看起来更像是分段三次函数生成的曲线图,而我的曲线图在我看来是线性的(或一阶的,如果更合适的话)。

您拥有的数据集看起来更像平滑曲线可以遵循的东西。你和SciPy之间没有问题;您对数据有问题

通过增加参数
s
,可以获得与数据越来越偏离的逐渐平滑的曲线图,最终接近三次多项式,这是数据的“最佳”最小二乘拟合。但这里“最好”的意思是“非常糟糕,可能一文不值”。平滑曲线可用于显示数据已遵循的模式。如果数据不符合平滑模式,则不应为了绘制而绘制曲线。第一个图上的数据点应按原样显示,无任何连接或近似曲线

数据来自9:00到16:00的每小时读数(其中一个17:00的零散值混合在一起-扔掉)。这种结构很重要。不要假装周二9:00是周一16:00后一小时发生的事情

数据可以通过每日总计进行有意义的汇总

Day         Total
2018-04-02  289841
2018-04-03  256293
2018-04-04  401004
2018-04-05  419054
2018-04-06  375993
2018-04-09  266233
2018-04-10  278118
2018-04-11  151390
2018-04-12  318497
2018-04-13  310578
以及每小时平均数(9:00时的平均事件数,全天等)

在这些事情上,我们可以观察到一些模式。这是每小时一次的:

hourly_averages = np.array([16698.6, 39705.2, 47451.9, 21758.8, 20941.5, 29086.1, 65627, 65411])
hours = np.arange(9, 17)
hourly_s = 0.1*np.diff(hourly_averages).max()**2
hourly_spline = interp.UnivariateSpline(hours, hourly_averages, s=hourly_s)
xx = np.linspace(min(hours), max(hours), 1000)  # 1000 is an arbitrary number here.
plt.plot(hours, hourly_averages, 'bo')
plt.plot(xx, hourly_spline(xx), 'r')
plt.show()

曲线显示午餐休息时间和下班高峰时间。我对
s
的选择是
0.1*np.diff(小时平均值)。max()**2
不是规范的,但它认识到
s
的比例是残差的平方。(). 对于每日平均值,我将使用相同的选择:

daily_totals = np.array([289841, 256293, 401004, 419054, 375993, 266233, 278118, 151390, 318497, 310578])
days = np.arange(len(daily_totals))
daily_s = 0.1*np.diff(daily_totals).max()**2
daily_spline = interp.UnivariateSpline(days, daily_totals, s=daily_s)
xx = np.linspace(min(days), max(days), 1000)  # 1000 is an arbitrary number here.
plt.plot(days, daily_totals, 'bo')
plt.plot(xx, daily_spline(xx), 'r')
plt.show()

这不太有用。也许我们需要更长时间的观察。也许我们不应该假装星期一在星期五之后。也许应该对一周中的每一天进行平均,以揭示一周的模式,但只有两周的时间是不够的



技术细节:方法
单变量样条线
选择尽可能少的节数,以便与数据的某个加权偏差平方和最多为
s
。对于大的
s
这意味着只有很少的节点,直到没有节点,我们得到一个三次多项式。需要多大的
s
取决于垂直方向上的振荡量,在本例中,振荡量非常高。

为什么说曲线图看起来是线性的?在第一个图中,放大间隔[20]样条曲线拟合看起来正确,执行得也正确。我不太理解它的问题。所以当你说“我显然错过了一些东西”,你是什么意思?绘图有什么问题,你希望它看起来如何?@WarrenWeckesser为不准确感到抱歉。我并不是真的想说“线性”。我添加了另一个绘图来帮助解释我的问题。@importantanceofbeingerre谢谢你的时间。我可能在
UnivariateSpline。我添加了一个指向更像我想要的绘图的链接。我通常使用
r
作为样条曲线。当我使用
gam
在r中进行样条曲线时,它看起来是正确的,也是我所期望的。谢谢你的回答。我实际上已经尝试过将
s
增加到一些荒谬的数字。例如
s=100
s=500
。我想我必须放大才能看到实际的平滑效果。我添加的最后一个图呢?它看起来像是
单变量样条线
只在提供的那些点上计算值,并简单地画了一条直线来连接它们。嗯……当我阅读时,只有14个点被传递到
单变量样条线
,图看起来不太复杂糟糕的是?唯一的区别是我使用的是
pyplot.plot
,答案是
pylab.plot
。只是为了确保每个人都在同一页上:如果你有7个点并绘制正弦曲线,
x=np.array([0,1,2,3,4,5,6]);y=np sin x;plot(x,y)
it,仅仅是因为您仅使用7个点对正弦进行采样。如果您使用1000个点对正弦进行采样,
x=np.linspace(0,61000)
,您当然会得到。@ImportanceOfBeingErnest所以它看起来确实是我应该更多使用的绘图。我将很快再尝试几次。非常感谢!
daily_totals = np.array([289841, 256293, 401004, 419054, 375993, 266233, 278118, 151390, 318497, 310578])
days = np.arange(len(daily_totals))
daily_s = 0.1*np.diff(daily_totals).max()**2
daily_spline = interp.UnivariateSpline(days, daily_totals, s=daily_s)
xx = np.linspace(min(days), max(days), 1000)  # 1000 is an arbitrary number here.
plt.plot(days, daily_totals, 'bo')
plt.plot(xx, daily_spline(xx), 'r')
plt.show()