Python 如何高效地对Pytables中的数据进行插值
我在pytables中有很长的时间-值对数组和表。我需要能够在这个数据上执行线性插值和零阶保持插值 目前,我正在使用pytables的逐列切片表示法将列转换为numpy数组,然后将numpy数组提供给scipy.interpolate.interp1d以创建插值函数 有更好的方法吗 我问这个问题的原因是,据我所知,将列转换为numpy数组基本上是将它们复制到内存中。这意味着,当我开始全速运行我的代码时,我将遇到麻烦,因为我将处理的数据集大到足以淹没我的桌面。如果我在这一点上错了,请纠正我Python 如何高效地对Pytables中的数据进行插值,python,numpy,scipy,interpolation,pytables,Python,Numpy,Scipy,Interpolation,Pytables,我在pytables中有很长的时间-值对数组和表。我需要能够在这个数据上执行线性插值和零阶保持插值 目前,我正在使用pytables的逐列切片表示法将列转换为numpy数组,然后将numpy数组提供给scipy.interpolate.interp1d以创建插值函数 有更好的方法吗 我问这个问题的原因是,据我所知,将列转换为numpy数组基本上是将它们复制到内存中。这意味着,当我开始全速运行我的代码时,我将遇到麻烦,因为我将处理的数据集大到足以淹没我的桌面。如果我在这一点上错了,请纠正我 另外,
另外,由于我将处理大量的数据,我怀疑编写一个迭代pytables数组/表的函数来自己进行插值会非常慢,因为我需要多次调用插值函数(大约是我试图插入的数据中记录的次数)。您的问题很难回答,因为内存和计算时间之间总是有一个折衷,您基本上要求不必牺牲其中任何一个,这是不可能的。
scipy.interpolate.interp1d()
要求阵列位于内存中,而写入核心外插值器则要求以调用次数线性查询磁盘
也就是说,你可以做一些事情,但没有一件是完美的
您可以尝试的第一件事是对数据进行下采样。这将通过下采样的因子减少内存中需要的数据。缺点是插值要粗得多。幸运的是,这很容易做到。只需为您访问的列提供步长。对于下采样因子为4你会做:
with tb.open_file('myfile.h5', 'r') as f:
x = f.root.mytable.cols.x[::4]
y = f.root.mytable.cols.y[::4]
f = scipy.interpolate.interp1d(x, y)
ynew = f(xnew)
如果您愿意,也可以根据可用内存调整此步长
或者,如果要为-xnew-插值的数据集仅存在于原始域的子集上,则可以只读取位于新邻域中的原始表的部分。如果模糊因子为10%,则可以执行以下操作:
query = "{0} <= x & x <= {1}".format(xnew.min()*0.9, xnew.max()*1.1)
with tb.open_file('myfile.h5', 'r') as f:
data = f.root.mytable.read_where(query)
f = scipy.interpolate.interp1d(data['x'], data['y'])
ynew = f(xnew)
在内存和I/O速度之间取得平衡始终是一个挑战。根据数据的规律性,您可能可以做一些事情来加速这些策略。不过,这应该足以让您开始
newlen = len(xnew)
chunks = 10
chunklen = newlen/ chunks
ynew = np.empty(newlen, dtype=float)
for i in range(chunks):
xnew_chunk = xnew[i*chunklen:(i+1)*chunklen]
query = "{0} <= x & x <= {1}".format(xnew_chunklen.min()*0.9,
xnew_chunklen.max()*1.1)
with tb.open_file('myfile.h5', 'r') as f:
data = f.root.mytable.read_where(query)
f = scipy.interpolate.interp1d(data['x'], data['y'])
ynew[i*chunklen:(i+1)*chunklen] = f(xnew_chunk)