Np.empty: initializes the array but doesn't bother to set the inside so you save looping through the array as you would have to with np.ones. But these can be fixed relatively easily. I should note though that this attempts to fix some things that looked weird in your function such as the draw_series / max-return index offset. My best attempt was def max_drawdown(returns): The fastest I could get this using python only is a bit less than twice the speed before. You might also want to look at what exactly this line does: draw_series = np.array(np.ones(np.size(returns)))Ĭan you time it and see if it is causing the performance problem? This probably won't substantially improve performance, though, because I expect that most of the slowness comes from the overhead associated with Python (interpretation of code). This could spare you from a lot of floating-point divisions, which are quite slow compared to multiplies. It may also make performance worse (it all depends on your general type of dataset):Ĭhange the if-else: if returns > max_return:ĭraw = returns * max_return_reciprocal I doubt it will improve performance substantially, but it's easy to give it a try. Will be true only rarely? If so, try the following. Of course, you run the risk of spending more time in I/O operations, which could well outweigh any performance gains of this approach.Ī less radical proposal: Do you expect that the if statement here: if returns > max_return: Another possibility is to simply dump your data to a file, have a C program process it and dump an output file which could then be read by your program. ![]() This won't be worth it unless you're working on a very large dataset. If you must use Python for whatever reason (such as your data structures coming from a Python environment), you could always use Swig or a similar tool to write a C program that does what you need and link that program to Python. You don't seem to be doing anything that's much more intensive than what is necessary to achieve your intended computation, so it is unlikely you can increase performance much more. ![]() If you want high-performance code, Python probably isn't the right language. Consider some comments to explain the reasoning draw_series = -(1 - max_draw) Your math seems inscrutable, but perhaps it makes sense in context. I have to recommend against r, as its not a common abbreviation and I think it makes the code hard to read. Use a compound assignment for r in range(unt()-1, 0, -1): Multiple assignments on one lined is also frowned upon in python. ![]() Just assign to it in the scope its used in. You declare draw far away from where it used. If you aren't going to use the ones you store in the array use numpy.empty which skips the initialization step. There is no reason to pass it to np.array afterwards. Max_returns = np.maximum.accumulate(returns)Ĭomments on your code: import numpy as npĭraw_series = np.array(np.ones(np.size(returns))) I think it may actually apply operations backwards, but you should be easily able to flip that. Untested, and probably not quite correct. One minor improvement is to replace returns = returns + 1 with returns += 1 which will operate in-place and avoid re-allocating the returns array. ![]() See if your algorithm can be expressed as a compiled numexprĬompile this function using Cython, f2py or ctypes Study your problem hard and see if you decompose it into numpy-only This is analogous to Numpy's accumulate but obviously there's no implementation of it for your particular algorithm. It would be trivial to replace your python loop with some Numpy indexing or broadcasting if it weren't for the pesky draw_series = -(1 - max_draw) line which operates on the next-to-be-computed item in the array. 100X speedup would be reasonable for large arrays once you eliminate the python loop. You are correct to point out that your implementation is terribly inefficient compared to most built-in Numpy operations of similar complexity.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |