【问题标题】:Pandas multiindex creation performancePandas 多索引创建性能
【发布时间】:2019-10-28 11:15:46
【问题描述】:

使用不同的类方法创建相等的pd.MultiIndex 的性能测试:

import pandas as pd

size_mult = 8
d1 = [1]*10**size_mult
d2 = [2]*10**size_mult

pd.__version__
'0.24.2'

.from_arraysfrom_tuplesfrom_frame

# Cell from_arrays
%%time
index_arr = pd.MultiIndex.from_arrays([d1, d2], names=['a', 'b'])
# Cell from_tuples
%%time
index_tup = pd.MultiIndex.from_tuples(zip(d1, d2), names=['a', 'b'])
# Cell from_frame
%%time
df = pd.DataFrame({'a':d1, 'b':d2})
index_frm = pd.MultiIndex.from_frame(df)

单元格的相应输出:

# from_arrays
CPU times: user 1min 15s, sys: 6.58 s, total: 1min 21s
Wall time: 1min 21s
# from_tuples
CPU times: user 26.4 s, sys: 4.99 s, total: 31.4 s
Wall time: 31.3 s
# from_frame
CPU times: user 47.9 s, sys: 5.65 s, total: 53.6 s
Wall time: 53.7 s

让我们检查一下这个案例的所有结果是否相同

index_arr.difference(index_tup)
index_arr.difference(index_frm)

所有行产生:

MultiIndex(levels=[[1], [2]],
           codes=[[], []],
           names=['a', 'b'])

那么为什么会有这么大的区别呢? from_arrays 几乎比 from_tuples 慢 3 倍。它甚至比创建 DataFrame 并在其上构建索引还要慢。

编辑:

我做了另一个更通用的测试,结果出人意料地相反:

np.random.seed(232)

size_mult = 7
d1 = np.random.randint(0, 10**size_mult, 10**size_mult)
d2 = np.random.randint(0, 10**size_mult, 10**size_mult)

start = pd.Timestamp.now()
index_arr = pd.MultiIndex.from_arrays([d1, d2], names=['a', 'b'])
print('ARR done in %f' % (pd.Timestamp.now()-start).total_seconds())

start = pd.Timestamp.now()
index_tup = pd.MultiIndex.from_tuples(zip(d1, d2), names=['a', 'b'])
print('TUP done in %f' % (pd.Timestamp.now()-start).total_seconds())
ARR done in 9.559764
TUP done in 70.457208

虽然源数据相同,但现在from_tuples 的速度明显变慢。

【问题讨论】:

    标签: python pandas performance multi-index


    【解决方案1】:

    你的第二个例子对我来说更有意义。查看 Pandas 的源代码,from_tuples actually calls from_arrays,所以我认为from_arrays 会更快。

    from_tuples 还在这里做了一些额外的步骤,这些步骤会花费更多时间:

    1. 你传入了一个zip(d1, d2),它实际上是一个迭代器。 from_tuplesconverts this into a list.
    2. 在转换为元组列表后,它会通过一个额外的步骤将其转换为list of numpy arrays
    3. 上一步iterates through the list of tuples twice,使from_tuples 明显比from_arrays 慢,马上开始。

    因此,总的来说,from_tuples 速度较慢我并不感到惊讶,因为它必须在到达 from_arrays 函数(其中iterates a couple more times,顺便说一句)它无论如何都使用。

    【讨论】:

      猜你喜欢
      • 2021-05-15
      • 1970-01-01
      • 2016-11-07
      • 2017-03-07
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 2012-01-31
      相关资源
      最近更新 更多