快速向 Pandas 数据框添加多列

Posted

技术标签:

【中文标题】快速向 Pandas 数据框添加多列【英文标题】:Add multiple columns to a Pandas dataframe quickly 【发布时间】: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 的行数较少,我不知道为什么。任何有关如何加快速度的建议将不胜感激。

【问题讨论】:

【参考方案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 数组,甚至无需考虑它或进行预转换。

以上是关于快速向 Pandas 数据框添加多列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 pyspark aws emr 中向现有数据框添加多列?

Pandas:如何向多索引数据框添加列?

无法向 pandas DataFrame 添加值

向熊猫数据框添加背景色

快速搜索 Pandas 数据框列

将列表中具有零值的多个列添加到 Pandas 数据框中