Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫df.loc[z,x]=y如何提高速度?_Python_Pandas_Optimization_Time Series - Fatal编程技术网

Python 熊猫df.loc[z,x]=y如何提高速度?

Python 熊猫df.loc[z,x]=y如何提高速度?,python,pandas,optimization,time-series,Python,Pandas,Optimization,Time Series,我已经确定了一个命令 timeseries.loc[z, x] = y 负责迭代中花费的大部分时间。现在我正在寻找更好的方法来加速它。循环甚至不包括50k元素(生产目标为~250k或更多),但已经需要20秒 这是我的代码(忽略上半部分,它只是计时助手) 有(不重要,不慢) 。 -->待优化代码在for循环中。 (T和T只是辅助函数&dict,用于计时。) 我每一步都计时。绝大多数时间: len(df.index)= 47160 times needed (total = 20.2 secon

我已经确定了一个命令

timeseries.loc[z, x] = y
负责迭代中花费的大部分时间。现在我正在寻找更好的方法来加速它。循环甚至不包括50k元素(生产目标为~250k或更多),但已经需要20秒

这是我的代码(忽略上半部分,它只是计时助手)

有(不重要,不慢)

-->待优化代码在for循环中。

(T和T只是辅助函数&dict,用于计时。)

我每一步都计时。绝大多数时间:

len(df.index)= 47160
times needed (total = 20.2 seconds) for each command:
{0: 1.102,
 1: 0.741,
 2: 0.243,
 3: 0.792,
 4: 17.371}
在最后一步中花费

timeseries.loc[sym, tsMean] = o
我已经下载并安装了pypy,但遗憾的是,它还不支持pandas

有没有办法加快填充2D阵列的速度

谢谢


编辑:抱歉,没有提到-“timeseries”也是一个数据帧:

timeseries = pd.DataFrame({"name": titles}, index=index)
我一直认为是最快的,但不是。速度更快:

import pandas as pd

df = pd.DataFrame({'A':[1,2,3],
                   'B':[4,5,6],
                   'C':[7,8,9],
                   'D':[1,3,5],
                   'E':[5,3,6],
                   'F':[7,4,3]})

print (df)
   A  B  C  D  E  F
0  1  4  7  1  5  7
1  2  5  8  3  3  4
2  3  6  9  5  6  3

print (df.at[2, 'B'])
6
print (df.ix[2, 'B'])
6
print (df.loc[2, 'B'])
6

In [77]: %timeit df.at[2, 'B']
10000 loops, best of 3: 44.6 µs per loop

In [78]: %timeit df.ix[2, 'B']
10000 loops, best of 3: 40.7 µs per loop

In [79]: %timeit df.loc[2, 'B']
1000 loops, best of 3: 681 µs per loop
编辑:

我尝试了
df
,差异是由
random造成的。randint
函数:

df = pd.DataFrame(np.random.rand(10**7, 5), columns=list('ABCDE'))


In [4]: %timeit (df.ix[2, 'B'])
The slowest run took 25.80 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 20.7 µs per loop

In [5]: %timeit (df.ix[random.randint(0, 10**7), 'B'])
The slowest run took 9.42 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 28 µs per loop

更新:从Pandas 0.20.1开始

=====================================================================

@jezrael提供了一个有趣的比较,我决定使用更多的索引方法并针对10M行DF重复它(实际上,在这种特殊情况下,大小并不重要):

设置:

In [15]: df = pd.DataFrame(np.random.rand(10**7, 5), columns=list('abcde'))

In [16]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000000 entries, 0 to 9999999
Data columns (total 5 columns):
a    float64
b    float64
c    float64
d    float64
e    float64
dtypes: float64(5)
memory usage: 381.5 MB

In [17]: df.shape
Out[17]: (10000000, 5)
结果显示为条形图:

定时数据作为DF:

In [88]: r
Out[88]:
       method  timing
0         loc   502.0
1        iloc   394.0
2          at    66.8
3         iat    32.9
4    ix_label    64.8
5  ix_integer   503.0

In [89]: r.to_dict()
Out[89]:
{'method': {0: 'loc',
  1: 'iloc',
  2: 'at',
  3: 'iat',
  4: 'ix_label',
  5: 'ix_integer'},
 'timing': {0: 502.0,
  1: 394.0,
  2: 66.799999999999997,
  3: 32.899999999999999,
  4: 64.799999999999997,
  5: 503.0}}
策划

ax = sns.barplot(data=r, x='method', y='timing')
ax.tick_params(labelsize=16)
[ax.annotate(str(round(p.get_height(),2)), (p.get_x() + 0.2, p.get_height() + 5)) for p in ax.patches]
ax.set_xlabel('indexing method', size=20)
ax.set_ylabel('timing (microseconds)', size=20)

如果在循环内添加行,则考虑性能问题;对于大约前1000到2000条记录,“my_df.loc”性能更好,通过增加循环中的记录数,性能逐渐变慢


如果你计划在一个大环内做一些事情(比如10米)‌ 你最好混合使用“iloc”和“append”;用iloc填充一个临时数据帧,直到大小达到1000左右,然后将其附加到原始数据帧,并empy临时数据帧。这将使您的性能提高10倍左右

我不知道什么类型的对象
timeseries
。但是,如果它有一个“.loc”方法,它可能有一个
.at
方法。如果您在特定位置分配,
.at
应该更快。编辑:抱歉,没有提到:timeseries是一个数据帧:timeseries=pd.dataframe({“name”:titles},index=index)我现在已经将它添加到OP中。我将研究它。at函数。非常感谢,@piRSquaredwow-wow。非常感谢你。这确实很有启发性。因此,我对这种缓慢的怀疑是有道理的。我选择了可能是最舒适的解决方案,使用.loc-但我购买它时,时间复杂度是.at和.iat的7.5到15.3倍-非常感谢,这是非常有价值的信息!完成。谢谢!非常感谢。不幸的是,我不能接受这两个答案。嗯。。。你的有一个非常容易阅读的直方图输出。但是@jezrael是第一个回答的,他的回答也很好。现在该怎么办?很有趣。非常感谢你!现在我想知道如何解释你的结果与@MaxU在那里报道的结果之间的差异:也许他的df是1000万行,而你的df很小?因此,也许.ix对于小数据帧是最快的,而.at/.iat对于大数据帧是最快的?我认为计时对于比较各种方法是最好的,并且在每台PC机中几乎没有什么不同。而且这些计时并不取决于数据帧的长度。而且,
iat
是最快的,但是你需要列的位置-如果不知道位置并且只知道列名,你不能使用iat-使用ix是最快的方法。最好的方法是解释它。因为你的两个答案都一样好。。。我已经投了一千枚硬币:sum([random.random()表示uuu在范围内(1000)])/1000,结果是0.4972785257694664-所以MaxU赢了,随机选择:-)祝你好运!
In [37]: %timeit df.loc[random.randint(0, 10**7), 'b']
1000 loops, best of 3: 502 µs per loop

In [38]: %timeit df.iloc[random.randint(0, 10**7), 1]
1000 loops, best of 3: 394 µs per loop

In [39]: %timeit df.at[random.randint(0, 10**7), 'b']
10000 loops, best of 3: 66.8 µs per loop

In [41]: %timeit df.iat[random.randint(0, 10**7), 1]
10000 loops, best of 3: 32.9 µs per loop

In [42]: %timeit df.ix[random.randint(0, 10**7), 'b']
10000 loops, best of 3: 64.8 µs per loop

In [43]: %timeit df.ix[random.randint(0, 10**7), 1]
1000 loops, best of 3: 503 µs per loop
In [88]: r
Out[88]:
       method  timing
0         loc   502.0
1        iloc   394.0
2          at    66.8
3         iat    32.9
4    ix_label    64.8
5  ix_integer   503.0

In [89]: r.to_dict()
Out[89]:
{'method': {0: 'loc',
  1: 'iloc',
  2: 'at',
  3: 'iat',
  4: 'ix_label',
  5: 'ix_integer'},
 'timing': {0: 502.0,
  1: 394.0,
  2: 66.799999999999997,
  3: 32.899999999999999,
  4: 64.799999999999997,
  5: 503.0}}
ax = sns.barplot(data=r, x='method', y='timing')
ax.tick_params(labelsize=16)
[ax.annotate(str(round(p.get_height(),2)), (p.get_x() + 0.2, p.get_height() + 5)) for p in ax.patches]
ax.set_xlabel('indexing method', size=20)
ax.set_ylabel('timing (microseconds)', size=20)