end <str>:'2013-01-22'
window <num>:10
tmp_data = data[data['date']<=end].tail(window*251)
上述代码要进行差不多 2000 次循环,这部分代码的执行时间占比高达 85%+,求问,如何提高这一行代码的执行速度?
某单次统计数据(单位:秒):
循环总耗时 :107.49908785695135
该条代码耗时:100.13774995734286
代码耗时占比:93.152%
PS:
1、试过随着循环缩减 data 前面的数据,结果更慢了。
2、原本 index 为 datetime,无厘头的将 date 赋值到 index,运算结束,然后再将原 index 赋值回去。速度提升一倍左右。如下:
循环总耗时 :45.289391494105644
该条代码耗时:37.87854096882086
代码耗时占比:83.637%
1
O14 2017-05-13 22:24:22 +08:00 via Android
按 date 字段排序,二分查找 end 位置,直接向前 slice。
代码不全不好说,建议先不用 Pandas,看看瓶颈在哪。 |
2
EmdeBoas 2017-05-13 22:48:12 +08:00
...不会用 v2 的贴图..直接上代码了 5000 次循环秒出 <br>
import datetime import numpy as np if __name__ == '__main__': array = np.array([]) for i in xrange(5000): year = np.random.randint(100) + 2000 month = np.random.randint(12) + 1 day = np.random.randint(27) + 1 array = np.append(array, datetime.datetime(year, month, day)) end = datetime.datetime(2050, 5, 3) print array[array[:]>end][-5:] |
4
kingmo888 OP |
5
herozhang 2017-05-13 23:23:56 +08:00 via iPhone
并行?
|
7
EmdeBoas 2017-05-13 23:34:49 +08:00 1
...我把数据量调到了 100W 然后试的
In [8]: def test(): ...: array = [] ...: for i in xrange(1000000): ...: year = np.random.randint(100) + 2000 ...: month = np.random.randint(12) + 1 ...: day = np.random.randint(28) + 1 ...: array.append(datetime.datetime(year, month, day)) ...: narray = np.array(array) ...: flag = datetime.datetime(2015, 5, 3) ...: print narray[narray[:]<=flag][-5:] ...: In [9]: %timeit test() [datetime.datetime(2012, 12, 11, 0, 0) datetime.datetime(2009, 5, 26, 0, 0) datetime.datetime(2014, 6, 12, 0, 0) datetime.datetime(2008, 11, 23, 0, 0) datetime.datetime(2010, 12, 12, 0, 0)] [datetime.datetime(2009, 4, 8, 0, 0) datetime.datetime(2013, 2, 10, 0, 0) datetime.datetime(2008, 2, 4, 0, 0) datetime.datetime(2010, 11, 2, 0, 0) datetime.datetime(2005, 8, 27, 0, 0)] [datetime.datetime(2004, 6, 19, 0, 0) datetime.datetime(2010, 5, 7, 0, 0) datetime.datetime(2012, 5, 15, 0, 0) datetime.datetime(2012, 6, 7, 0, 0) datetime.datetime(2000, 1, 5, 0, 0)] [datetime.datetime(2014, 11, 6, 0, 0) datetime.datetime(2005, 9, 15, 0, 0) datetime.datetime(2008, 11, 5, 0, 0) datetime.datetime(2007, 6, 9, 0, 0) datetime.datetime(2003, 11, 10, 0, 0)] 1 loop, best of 3: 4.18 s per loop |
8
kingmo888 OP @EmdeBoas 已感谢,还是无法大幅解决我的问题(可能我技术渣渣,嘿嘿),但还是感谢。
data 是 pandas 中的 DataFrame 格式数据,牵扯到一个 df 切片的问题。目前我做这样的尝试: 循环之前,a=np.array(data['date']) 循环中, b=a[a<=end] index=len(b) 利用其行号来查找: tmp_data = data.loc[data.index[index-window*251:index],:] 这样速度提升了 8 秒左右。全部循环完差不多 36s+。 |
10
sagaxu 2017-05-13 23:56:13 +08:00 via Android
数据贴网盘里,明天看看
|
11
EmdeBoas 2017-05-13 23:59:51 +08:00 1
老哥 你别老复杂化问题啊.....loc 和 iloc 要少用 效率很低的
In [17]: def test(): ...: array = [] ...: other = [] ...: for i in xrange(1000000): ...: [TAB]other.append(i) ...: [TAB]year = np.random.randint(100) + 2000 ...: [TAB]month = np.random.randint(12) + 1 ...: [TAB]day = np.random.randint(28) + 1 ...: [TAB]array.append(datetime.datetime(year, month, day)) ...: narray = np.array(array) ...: flag = datetime.datetime(2015, 5, 3) ...: df = pd.DataFrame() ...: df['date'] = narray ...: df['other'] = other ...: print df[narray[:]<=flag][-5:] ...: In [18]: %timeit test() date other 999979 2006-07-05 999979 999980 2012-09-19 999980 999981 2010-05-13 999981 999990 2007-10-14 999990 999996 2008-10-19 999996 date other 999979 2002-08-01 999979 999983 2001-10-01 999983 999984 2007-04-05 999984 999988 2014-04-21 999988 999991 2008-01-06 999991 date other 999977 2004-05-04 999977 999981 2004-05-05 999981 999990 2003-10-04 999990 999991 2003-03-28 999991 999992 2002-12-09 999992 date other 999964 2006-12-13 999964 999970 2012-07-07 999970 999971 2009-12-15 999971 999976 2004-07-22 999976 999982 2009-11-14 999982 1 loop, best of 3: 4.58 s per loop In [19]: |
12
EmdeBoas 2017-05-14 00:01:40 +08:00
@kingmo888 (⊙﹏⊙)....我不是做 python 的( python 的并行库我都没用过) 只是做数模比赛做多了对 numpy 和 pandas 熟悉一点.... java 的 hadoop 我可能还能帮你看看...
|
13
herozhang 2017-05-15 14:58:09 +08:00
100w 数据量,在我的 mbp 上跑:
单核: 7.87 s ± 175 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 并行 4 核: 1.88 s ± 9.23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) |
14
herozhang 2017-05-15 15:00:16 +08:00
要进一步加速,可以考虑用 pypy ?
|
15
ruoyu0088 2017-05-16 21:38:10 +08:00
两千次循环中什么是变量?循环中进行了哪些计算?
对于你贴出来的那一行代码,下面的方法可能更快。 data.take(np.where((data["date"] <= end).values)[-window*251:][0]) |