快速将多个列添加到Pandas数据框中

时间:2015-03-21 22:01:58

标签: python performance numpy pandas dataframe

我正在编写一些性能敏感的代码,我必须快速向Pandas数据帧中添加大量列。

通过从dict构造第二个数据帧并连接它们,我设法通过天真地重复df[foo] = bar获得了3倍的提升:

def mkdf1(n):
    df = pd.DataFrame(index=range(10,20), columns=list('qwertyuiop'))
    for i in xrange(n):
        df['col%d' % i] = range(i, 10+i)
    return df

def mkdf2(n):
    df = pd.DataFrame(index=range(10,20), columns=list('qwertyuiop'))
    newcols = {}
    for i in xrange(n):
        newcols['col%d' % i] = range(i, 10+i)
    return pd.concat([df, pd.DataFrame(newcols, index=df.index)], axis=1)

时间显示出实质性改善:

%timeit -r 1 mkdf1(100)
100 loops, best of 1: 16.6 ms per loop

%timeit -r 1 mkdf2(100)
100 loops, best of 1: 5.5 ms per loop

我可以在这里进行任何其他优化吗?

编辑:此外,concat电话在我的真实代码中比我的玩具示例要长得多;特别是get_result函数需要更长的时间,尽管生产df具有较少的行,我无法弄清楚原因。任何关于如何提高速度的建议都将不胜感激。

1 个答案:

答案 0 :(得分:3)

我对你的数据帧看起来应该是什么感到有点困惑,但是通过一般技术很容易加快这一点。基本上对于pandas / numpy速度,如果可能,您要避免使用for和任何concat/merge/join/append

这里最好的选择是最有可能使用numpy来创建一个数组,该数组将作为数据帧的输入,然后根据您的喜好命名列。就计算时间而言,这两个操作都应该是微不足道的。

这是numpy部分,看起来你已经知道如何构建列名。

%timeit pd.DataFrame(  np.ones([10,100]).cumsum(axis=0) 
                     + np.ones([10,100]).cumsum(axis=1) )
10000 loops, best of 3: 158 µs per loop

我认为你正试图做这样的事情? (如果没有,只要你不熟悉它就检查numpy,它有各种各样的数组操作,可以很容易地做你想做的任何事情。)

In [63]: df.ix[:5,:10]
Out[63]: 
   0   1   2   3   4   5   6   7   8   9   10
0   2   3   4   5   6   7   8   9  10  11  12
1   3   4   5   6   7   8   9  10  11  12  13
2   4   5   6   7   8   9  10  11  12  13  14
3   5   6   7   8   9  10  11  12  13  14  15
4   6   7   8   9  10  11  12  13  14  15  16
5   7   8   9  10  11  12  13  14  15  16  17