在pandas系列中设置值很慢,为什么?

时间:2015-05-15 19:27:28

标签: python pandas

问题

有谁知道为什么直接在熊猫系列上设置项目的速度非常慢?我做错了什么,或者只是它的方式?

我运行了几个测试,看看在pandas Series对象上设置值的最快方法是什么。以下是从快到慢排序的结果:

初始化数组,使用整数索引设置,创建系列

%%timeit
a = np.empty(1000, dtype='float')
for i in range(len(a)):
    a[i] = 1.0
s = pd.Series(data=a)

1000个循环,最佳3:630μs/循环

创建空列表,使用追加添加项目,创建系列

%%timeit
l = []
for i in range(1000):
    l.append(1.0)
s = pd.Series(data=l)

1000个循环,最佳3:每循环1.05毫秒

初始化数组,创建系列,使用set_value

进行设置
%%timeit
a = np.empty(1000, dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.set_value(i, 1.0)

100个循环,最佳3:每循环18.5毫秒

初始化数组,创建系列,使用整数索引设置

%%timeit
a = np.empty(1000, dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s[i] = 1.0

10个循环,最好是每个循环3:30.2 ms

初始化数组,创建系列,使用iat设置

%%timeit
a = np.empty(1000, dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.iat[i] = 1.0

10个循环,最好为3:每循环36.2 ms

初始化数组,创建系列,使用iloc设置

%%timeit
a = np.empty(1000, dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.iloc[i] = 1.0

1个循环,最好是每循环3:280 ms

3 个答案:

答案 0 :(得分:5)

来自docs

  

由于使用[]进行索引必须处理很多情况(单标签   访问,切片,布尔索引等),它有一点开销   为了找出你所要求的东西。

所以我得到的内容应该具有可比性:

In [13]:

%%timeit
a = np.empty(1000,dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.iat[i] = 1.0
10 loops, best of 3: 23.3 ms per loop
In [14]:

%%timeit
a = np.empty(1000,dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.iloc[i] = 1.0
10 loops, best of 3: 159 ms per loop

其他测试:

In [15]:

%%timeit
l = []
for i in range(1000):
    l.append(1.0)
s = pd.Series(data=l)
1000 loops, best of 3: 525 µs per loop
In [16]:

%%timeit
a = np.empty(1000,dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s.set_value(i,1.0)
100 loops, best of 3: 10.1 ms per loop
In [17]:

%%timeit
a = np.empty(1000,dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    s[i] = 1.0
100 loops, best of 3: 17.5 ms per loop

答案 1 :(得分:1)

我认为这些方法甚至可以更快地将系列初始化为常数值:

基线

%%timeit
a = np.empty(1000, dtype='float')
for i in range(len(a)):
    a[i] = 1.0
s = pd.Series(data=a)

10000 loops, best of 3: 121 µs per loop

替代方案

%%timeit
s = pd.Series(np.empty(1000, dtype='float')) * 1.

10000 loops, best of 3: 99.5 µs per loop

%%timeit
constant = 5.
s = pd.Series(np.ones(1000)) * constant

10000 loops, best of 3: 85.3 µs per loop

答案 2 :(得分:1)

我想出了直接在系列对象上设置值时如何超越索引开销:

a = np.empty(1000,dtype='float')
s = pd.Series(data=a)
for i in range(len(a)):
    a[i] = 1.0

从numpy数组初始化Series时,不会复制数据。如果引用保留在原始数组中,您只需在其上设置值!