【问题标题】:Add multiple columns to a Pandas dataframe quickly快速向 Pandas 数据框添加多列
【发布时间】:2015-05-25 03:55:56
【问题描述】:

我正在编写一些对性能敏感的代码,我必须在其中快速向 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 的行数较少,我不知道为什么。任何有关如何加快速度的建议将不胜感激。

【问题讨论】:

    标签: python performance numpy pandas dataframe


    【解决方案1】:

    我对您的数据框应该是什么样子感到有些困惑,但使用通用技术很容易加快速度。基本上对于 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
    

    【讨论】:

    • 嗯。出于某种原因,我认为 DataFrame 按列存储,而不是按块存储,因此 df 将不得不切碎 numpy 数组并且它不会更快。无论如何,非常感谢您的解释!
    • 两个简短的后续问题:1)如果我从已经提供给我的数据框 df 开始,为我要添加的列构造一个 numpy 数组是否合理,以及然后在 numpy 级别将其连接到df.values?或者我应该创建一个全新的 numpy 数组,将df.values 写入其中,然后将我的新列写入其中?
    • 2) 如果我有一个混合类型的数据框,这是否仍然有效(使用带有dtype=object 的 numpy 数组)?或者 Pandas 是否会使用混合类型做奇怪的事情,从而导致速度变慢?
    • 抱歉,对于 (1) 或 (2),我真的没有任何一般性建议,但我也没有看到您计划做的任何问题。老实说,我只是先寻求简单易读的解决方案。如果这些太慢,请尝试其他方法并在此处发布特定的性能问题。
    • 关于您的第一条评论,请注意,pandas 是建立在 numpy 之上的,因此它们通常相处得很好。您通常可以执行 a+b 之类的操作,其中 a 是数据帧,b 是 numpy 数组,甚至无需考虑它或进行预转换。
    猜你喜欢
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多