Pandas优化
我写了一个用pandas处理数据的函数。下面贴出了我用%prun
对这个函数进行性能分析的日志(只贴了前几行)。我想优化我的代码,因为我需要调用这个函数超过4000次,而运行一次这个函数就花了37.7秒。
看起来最耗时间的部分是numpy.ndarray
中的nonzero
。由于我几乎所有的操作都是基于pandas
的,我想知道在pandas
中哪些函数会大量依赖这个方法?
我的操作主要是基于datetimeindex
进行数据框切片,使用df.ix[]
,以及使用pandas.merge()
进行数据框合并。
我知道不发我的实际代码很难判断,但我的代码太长了,发出来也没什么意义,而且大部分操作都是临时的,所以我不能把它重写成小代码发到这里。
16439731 function calls (16108083 primitive calls) in 37.766 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
7461 3.712 0.000 3.712 0.000 {method 'nonzero' of 'numpy.ndarray' objects}
244 1.731 0.007 5.434 0.022 index.py:1126(_partial_date_slice)
122 1.655 0.014 1.655 0.014 {pandas.algos.inner_join_indexer_int64}
610 1.578 0.003 1.578 0.003 {method 'factorize' of 'pandas.hashtable.Int64Factorizer' objects}
118817 0.764 0.000 0.764 0.000 {method 'reduce' of 'numpy.ufunc' objects}
22474 0.753 0.000 0.917 0.000 index.py:409(is_unique)
353210 0.669 0.000 1.228 0.000 {numpy.core.multiarray.array}
1577935 0.596 0.000 0.925 0.000 {isinstance}
1221 0.511 0.000 0.516 0.000 index.py:402(is_monotonic)
183 0.427 0.002 0.427 0.002 {pandas.algos.left_outer_join}
34529 0.376 0.000 1.286 0.000 index.py:98(__new__)
12356 0.358 0.000 0.358 0.000 {method 'take' of 'numpy.ndarray' objects}
3812 0.352 0.000 0.352 0.000 {pandas.algos.take_2d_axis0_int64_int64}
610 0.344 0.001 0.349 0.001 index.py:35(wrapper)
981 0.334 0.000 0.335 0.000 {method 'copy' of 'numpy.ndarray' objects}
1 个回答
0
df.ix[]这个方法有点不太稳定,它主要是通过标签来查找数据,但也可以用整数位置来作为备用。建议你使用.loc[]这个方法。如果你只传入一个标签,它会返回那个标签对应的行数据。你也可以通过传入一个范围来切片数据。所以,不要这样写:
df.ix[begin_date:end_date]
可以试试这样:
df.loc[begin_date:end_date]
如果想要更快,可以使用基于整数的切片方法.iloc[]。因为你本来就要遍历索引,所以可以在循环中加上enumerate(),然后使用enumerate()的值,也就是:
df.iloc[4:9]
在我的电脑上,.iloc的速度大约是.loc的两倍。