快速向 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 数据框添加多列的主要内容,如果未能解决你的问题,请参考以下文章