构建Pandas DataFrame时避免循环



我有一个带有三列的初始Pandas DataFrame,其中一列包含字符串列表。目标是将每一行拆分为与obj列中的项目一样多的元素,例如:

from    to      obj
--------------------
abc     xyz     [foo, bar]
def     uvw     [gee]
ghi     rst     [foo, bar, baz]

变为:

from    to      obj
--------------------
abc     xyz     foo
abc     xyz     bar
def     uvw     gee
ghi     rst     foo
ghi     rst     bar
ghi     rst     baz

目前我是这样做的:

transformed = pd.DataFrame(columns=['from', 'to', 'obj'])
for index, row in origin.iterrows():
for obj in row['obj']:
transformed = transformed.append(pd.Series({
'from':     row['from'],
'to':       row['to'],
'obj':      obj
}), ignore_index=True)

这非常好,只是速度慢得令人痛苦。如果origin有100000个元素,那么计算transformed可能需要一个小时。

有没有一种矢量化的方法可以获得相同的结果,而不必求助于Python循环?

本质上,您是根据列重复链接值。

因此,您可以根据需要使用np.repeatitertools.chain。该解决方案对于少量列是有效的,如您的示例所示。

import numpy as np
from itertools import chain
# set up dataframe
df = pd.DataFrame({'from': ['abc', 'def', 'gfhi'],
'to': ['xyz', 'uvw', 'rst'],
'obj': [['foo', 'bar'], ['gee'], ['foo', 'bar', 'baz']]})
# calculate length of each list in obj
lens = df['obj'].map(len)
# calculate result, repeating or chaining as appropriate
res = pd.DataFrame({'from': np.repeat(df['from'], lens),
'to': np.repeat(df['to'], lens),
'obj': list(chain.from_iterable(df['obj']))})
print(res)
from   to  obj
0   abc  xyz  foo
0   abc  xyz  bar
1   def  uvw  gee
2  gfhi  rst  foo
2  gfhi  rst  bar
2  gfhi  rst  baz

最新更新