Python 插值:使用np.interp和更改的值
我有一个300万行数据框,其中包含不同的值:Python 插值:使用np.interp和更改的值,python,pandas,scipy,Python,Pandas,Scipy,我有一个300万行数据框,其中包含不同的值: d a0 a1 a2 0.5 10.0 5.0 1.0 0.8 10.0 2.0 0.0 我想用线性插值(a0,a1,a2)填充第四列,取“d”情况下的值 newcol是a[int(d)]和a[int(d+1)]之间的加权平均值,例如,当d=0.8时,newcol=0.2*a0+0.8*a1,因为0.8是0和1之间的80% 我发现可以使用np.interp,但我无法将这三个列名放入变量): 真的
d a0 a1 a2
0.5 10.0 5.0 1.0
0.8 10.0 2.0 0.0
我想用线性插值(a0,a1,a2)填充第四列,取“d”情况下的值
newcol是a[int(d)]和a[int(d+1)]之间的加权平均值,例如,当d=0.8时,newcol=0.2*a0+0.8*a1,因为0.8是0和1之间的80%
我发现可以使用np.interp,但我无法将这三个列名放入变量):
真的会给我
d a0 a1 a2 newcol
1.5 10.0 5.0 1.0 250.0
0.8 10.0 2.0 0.0 180.0
但我无法指定值向量的变化:
df["newcol"]=np.interp(df["d"],[0,1,2], df[["a0","a1","a2"]])
给我以下回溯:
文件“C:\Python27\lib\site packages\numpy\lib\function\u base.py”,第1271行,在interp中
返回编译的_interp(x,xp,fp,左,右)
ValueError:对象对于所需数组太深
有没有办法对每行的值使用不同的向量?你能想出解决办法吗
基本上,我无法根据定义创建此新列:
分段线性函数的x=列“d”中的值是多少
在给定点之间,这些点的值在“ai”列中描述
编辑:以前,我使用了scipy.interp1d,它不节省内存,该评论帮助我部分解决了我的问题
编辑2:
我尝试了来自ev br的方法,该方法声明我必须尝试自己编写循环代码
for i in range(len(tps)):
columns=["a1","a2","a3"]
length=len(columns)
x=np.maximum(0,np.minimum(df.ix[i,"d"],len-2))
xint = np.int(x)
xfrac = x-xint
name1=columns[xint]
name2=columns[xint+1]
tps.ix[i,"Multiplier"]=df.ix[i,name1]+xfrac*(df.ix[i,name2]-tps.ix[i,name1])
上面的循环大约每秒循环50次,所以我想我有一个主要的优化问题。在数据帧上工作的哪一部分我做错了 可能来得有点晚,但我会使用np.interpolate和pandas的apply函数。在您的示例中创建数据帧:
t = pd.DataFrame([[1.5,10,5,1],[0.8,10,2,0]], columns=['d', 'a0', 'a1', 'a2'])
然后是应用功能:
t.apply(lambda x: np.interp(x.d, [0,1,2], x['a0':]), axis=1)
这将产生:
0 3.0
1 3.6
dtype: float64
这在“正常”数据集上是完全可用的。但是,数据帧的大小可能需要更好/更优化的解决方案。处理时间呈线性扩展,我的机器每秒时钟为10000行,这意味着300万行需要5分钟…好的,我有第二个解决方案,它使用numexpr模块。这种方法更加具体,但速度也更快。我已经测量了整个过程,100万行需要733毫秒,这还不错 因此,我们与之前一样拥有原始数据帧:
t = pd.DataFrame([[1.5,10,5,1],[0.8,10,2,0]], columns=['d', 'a0', 'a1', 'a2'])
我们导入模块并使用它,但它要求我们将使用“a0”和“a1”或“a1”和“a2”作为线性插值的下限/上限的两种情况分开。我们还准备了数字,以便将它们输入到相同的评估中(因此为-1)。我们通过创建3个具有插值值(最初为:“d”)和限制的数组来实现这一点,具体取决于“d”的值。因此,我们:
import numexpr as ne
lim = np.where(t.d > 1, [t.d-1, t.a1, t.a2], [t.d, t.a0, t.a1])
然后我们计算简单线性插值表达式,最后将其添加为新列,如下所示:
x = ne.evaluate('(1-x)*a+x*b', local_dict={'x': lim[0], 'a': lim[1], 'b': lim[2]})
t['IP'] = np.where(t.d > 1, x+1, x)
如果您只需要线性插值,
numpy.interp
可能更合理。或者,您可以按照您显示的方式计算apply函数中的加权平均值。感谢您的评论,我现在使用np.interp,我更接近我的答案,因此我相应地修改了我的问题(现在更清楚了)既然你改变了这个问题,我对编写一个详细的回答就失去了兴趣,但基本上:在数据帧的行上使用for循环为自己编写一个解决方案,然后把它交给cython,就一切就绪了。
import numexpr as ne
lim = np.where(t.d > 1, [t.d-1, t.a1, t.a2], [t.d, t.a0, t.a1])
x = ne.evaluate('(1-x)*a+x*b', local_dict={'x': lim[0], 'a': lim[1], 'b': lim[2]})
t['IP'] = np.where(t.d > 1, x+1, x)