首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数据帧中使用多个插值函数

在数据帧中使用多个插值函数
EN

Stack Overflow用户
提问于 2019-04-24 20:14:15
回答 1查看 32关注 0票数 0

我有一个包含许多列的大型数据框架。为了简单起见,让我们这样说:

代码语言:javascript
复制
df_sample = pd.DataFrame({'a':np.arange(10)})

我需要在df_sample中定义一个新的列(比如列'b'),它需要使用一些插值函数,它的参数取自列'a‘。

现在,问题是每行的插值函数是不同的。对于每一行,我从不同的1D网格进行插值;因此,我对每一行都有不同的插值函数。所以,我所做的就是预先生成这些插值函数,并将它们存储到一个数组中。仅给出一个示例,显示了生成样本数组“list_interpfns”的以下代码

代码语言:javascript
复制
list_interpfns = np.array([None]*10)
for j in range(10):
    list_interpfns[j] = scipy.interpolate.interp1d(np.linspace(0,10*(j+1),10),np.linspace(0,50,10))

要生成df_sample.bj,我需要使用带有参数df_sample.aj的list_interpfnsj。因为我不能直接应用列公式来达到这个目的,所以我把它放在一个循环中。

代码语言:javascript
复制
df_sample['b'] = 0
for j in range(10):
    df_sample.loc[j,'b'] = list_interpfns[j](df_sample.a[j])

问题是这个操作需要很长时间。在这个小例子中,计算可能看起来很快。但我的实际程序要大得多,当我比较所有操作所用的时间时,这个特定的操作序列占用了总时间的84%;我需要加快速度。

如果有一些方法可以避免for循环(例如使用df.apply或其他方法),那么我相信它可以减少操作时间。你能给出可能的替代方案吗?

EN

回答 1

Stack Overflow用户

发布于 2019-04-24 23:49:45

考虑避免初始化和更新数组和序列的多个for循环和记账,并使用Series.apply()将列值传递到函数构建和函数参数中

代码语言:javascript
复制
def interp_(j):
    return scipy.interpolate.interp1d(np.linspace(0,10*(j+1),10), np.linspace(0,50,10))

df_sample['b_'] = df_sample['a'].apply(lambda x: interp_(x)(x))

结果复制您的原始结果

代码语言:javascript
复制
df_sample
#    a         b        b_
# 0  0  0.000000  0.000000
# 1  1  2.500000  2.500000
# 2  2  3.333333  3.333333
# 3  3  3.750000  3.750000
# 4  4  4.000000  4.000000
# 5  5  4.166667  4.166667
# 6  6  4.285714  4.285714
# 7  7  4.375000  4.375000
# 8  8  4.444444  4.444444
# 9  9  4.500000  4.500000

尽管Series.apply()仍然是一个循环,但计时表明处理速度会稍微快一些:

代码语言:javascript
复制
def run1():
    list_interpfns = np.array([None]*10)
    for j in range(10):
        list_interpfns[j] = scipy.interpolate.interp1d(np.linspace(0,10*(j+1),10),
                                                       np.linspace(0,50,10))            
    df_sample['b'] = 0
    for j in range(10):
        df_sample.loc[j,'b'] = list_interpfns[j](df_sample.a[j])

def run2():
    def interp_(j):
        return scipy.interpolate.interp1d(np.linspace(0,10*(j+1),10), np.linspace(0,50,10))

    df_sample['b_'] = df_sample['a'].apply(lambda x: interp_(x)(x))

if __name__=='__main__':
    from timeit import Timer

    f1 = Timer("run1()", "from __main__ import run1")
    res1 = f1.repeat(repeat=100, number=1)
    print('LOOP: {}'.format(np.mean(res1)))

    f2 = Timer("run2()", "from __main__ import run2")
    res2 = f2.repeat(repeat=100, number=1)
    print('APPLY: {}'.format(np.mean(res2)))

# LOOP: 0.006322918700000002
# APPLY: 0.0015046094699999867
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55829797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档