使用numpy减去两个交错的,基于不同时间序列数组?

2024-10-08 20:17:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数据集,a[ts1]b[ts2],其中ts1和{}是在不同的时间(在不同的基础上?)获取的时间戳。我想把索引的顺序改成绘图。在

所以我想用numpy来做一个小例子,我意识到我不知道numpy是否以及如何执行这个操作——但是使用向量,避免for循环。我举了一个例子(如下),它将a[ts1]和{}定义为numpy名为a_npb_np的结构化数组:

array([(0.0, 0.0), (0.8865606188774109, 0.30000001192092896),
       (1.6939274072647095, 0.6000000238418579),
       (2.3499808311462402, 0.8999999761581421)], ...
      dtype=[('a', '<f4'), ('ts1', '<f4')])
array([(0.3973386585712433, 0.10000000149011612),
       (0.7788366675376892, 0.20000000298023224),
       (1.4347121715545654, 0.4000000059604645), (1.6829419136047363, 0.5)], ...
      dtype=[('b', '<f4'), ('ts2', '<f4')])

所以我的问题是:

  • 这类数组/问题叫什么?只是“时间序列”数组吗?基本上,它们描述的是一维信号,但由于时间戳必须保留,所以它是一个二维数组;而且由于“时间”列可以有任何含义,我想它可以被推广到(值)列中数组值的插值,而不是(时间/索引)列中的“索引”值。在
  • numpy是否可以执行向量化操作,其中数组在被减去之前在“时间”中被正确地插值?在

在寻找这方面的信息时,我发现了pandas: Python Data Analysis Library;我想我应该改用它,因为它有一个“时间序列”功能——但在本例中,我不需要任何复杂的采样值插值——只需要一个“步进”或“保持”(基本上,没有插值);这就是为什么我在徘徊,如果numpy能够以矢量化的方式实现这一点。否则,下面的示例使用for循环。在


该示例将生成如下图像:

array-timeseries

数组ab表示在不同时间获取的值,这由它们各自的impulses表示;alines绘制(因此,在绘制之前进行线性插值),但是b与{}一起绘制(以指示存在的实际值)

数组d1表示构造数组时所采用的“原始”差异b[t]-a[t]显然,我实际上无法访问这些数据,因此我必须从采样值开始工作。在这种情况下,差异b[ts2]-a[ts1]显示为数组/信号d2,再次显示为steps,以强调相对于“原始”所犯的错误。这个d2是我想用numpy来计算的(但是在下面,它是在相同的for循环中计算的)。在

我用绘图软件所犯的错误是按索引得到一个ba,或者b[i]-a[i];这显示为数组/信号e-并且如图所示,它与它本应表示的内容不符。只有当两个信号中的采样间隔不均匀时才会出现这种情况;在代码中尝试modulowith = 2,那么{}实际上并不是那么糟糕——但是,我的实际情况中时间戳不均匀,所以{}对我没有任何帮助。在

下面是代码,它也调用gnuplot(在python2.7上测试,numpy1.5我想):

^{pr2}$

感谢@runnerup的回答,这里有一个稍微冗长(用于语法示例)numpy的解决方案:

# create union of both timestamp arrays as tsz
ntz = np.union1d(b_np['ts2'], a_np['ts1'])
# interpolate `a` values over tsz
a_z = np.interp(ntz, a_np['ts1'], a_np['a'])
# interpolate `b` values over tsz
b_z = np.interp(ntz, b_np['ts2'], b_np['b'])
# create structured arrays for resampled `a` and `b`,
# indexed against tsz timestamps
a_npz = np.array( [ (tz,az) for tz,az in zip(ntz,a_z) ],
  dtype=[('tsz', 'f4'), ('a', 'f4')] )
b_npz = np.array( [ (tz,bz) for tz,bz in zip(ntz,b_z) ],
  dtype=[('tsz', 'f4'), ('b', 'f4')] )
# subtract resized array
e_npz = np.subtract(b_npz['b'], a_npz['a'])
e_str = ""

# check:
pprint(e_npz[:4])
# gnuplot string:
for ts, ie in zip(ntz, e_npz):
  e_str += "%.03f %.06f\n" % (ts, ie)

这是线性插值的,因此它与上面的d2不同,但仍然非常适合。在

如果没有那些创建数组的for循环,那么它是矢量化的——原则上我甚至不必创建那些数组——只想看看它们看起来像结构化的数组。。总之,我想我希望有一个单行程序来实现这一点,使用结构化数组(也就是说,也可以处理字段名)。在


Tags: numpyfor信号np时间数组array插值
1条回答
网友
1楼 · 发布于 2024-10-08 20:17:05

这是一个试图说服你转换到pandas:)

import numpy as np
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt

# one minute interval
start = dt.datetime.now( )
end = start + dt.timedelta( minutes=1 )

# sin curve at seconds frequancy
idx1 = pd.date_range( start, end, freq='S' )
ts1 = pd.Series( np.sin( np.linspace( 0, 4 * np.pi, len( idx1 ) ) ), index=idx1 )

# cosine curve at milisecond frequency
idx2 = pd.date_range( start, end, freq='L' )
ts2 = pd.Series( np.cos( np.linspace( 0, 4 * np.pi, len( idx2 ) ) ), index=idx2 )

现在len( ts1 ) = 61和{},频率不同

^{pr2}$

你会得到:

time series

编辑:出于插值目的,您可以在statsmodels中使用非参数方法,因此基本上可以在另一个序列的频率处插值一个序列,然后减去两个序列:

import statsmodels.api as sm
n = 1000
x = np.linspace( 0, 1, n )
y = np.random.randn( n ).cumsum( )
z = sm.nonparametric.lowess( y, x, return_sorted=False, frac=.05)

ax.plot( x, y, 'Blue', linestyle=' ' )
ax.plot( x, z, color='DarkRed' )

bm

相关问题 更多 >

    热门问题