mercredi 30 août 2017

Fill array combining segmented limits and number of elements stored in a separated array

I need to improve as much as possible the performance of the function defined below. It is called millions of times, and the for loop is currently the bottleneck of my code.

The function takes ranges defined in x and a number of elements inside each range defined in y. If the number of elements N in a range is < 1, combine it with adjacent upper segments until N>1. When this condition is fulfilled, generate a random number of N elements within that range, and store the result in the final array d.

# Sample data. Changes with every call to func().
x = np.arange(0.11, 1000., 0.1)
y = [1881.44972, 719.75073, 372.08464, 241.89332, 175.18145, 121.59943, 83.14836, 60.02836, 45.13496, 35.02594, 27.87664, 22.6501, 18.72337, 15.70481, 13.33868, 11.45254, 9.92687, 8.67683, 7.6409, 6.77366, 6.04099, 5.41692, 4.88137, 4.41865, 4.01638, 3.66464, 3.35548, 3.08242, 2.84015, 2.6243, 2.43123, 2.2579, 2.10178, 1.96069, 1.8328, 1.71655, 1.6106, 1.51378, 1.42511, 1.3437, 1.2688, 1.19975, 1.13596, 1.07693, 1.02221, 0.97139, 0.92411, 0.88007, 0.83898, 0.80059, 0.76467, 0.73102, 0.69945, 0.6698, 0.64193, 0.61568, 0.59095, 0.56762, 0.54559, 0.52477, 0.50507, 0.48641, 0.46873, 0.45195, 0.43602, 0.42089, 0.40649, 0.3928, 0.37975, 0.36732, 0.35547, 0.34415, 0.33335, 0.32302, 0.31315, 0.30371, 0.29467, 0.28601, 0.27771, 0.26975, 0.26211, 0.25479, 0.24775, 0.24099, 0.23448, 0.22823, 0.22222, 0.21643, 0.21085, 0.20548, 0.2003, 0.1953, 0.19049, 0.18584, 0.18135, 0.17702, 0.17283, 0.16879, 0.16488, 0.16109, 0.15744, 0.15389, 0.15047, 0.14715, 0.14393, 0.14082, 0.1378, 0.13487, 0.13203, 0.12928, 0.1266, 0.12401, 0.12149, 0.11905, 0.11667, 0.11436, 0.11212, 0.10994, 0.10782, 0.10576, 0.10375, 0.1018, 0.0999, 0.09805, 0.09625, 0.0945, 0.09279, 0.09113, 0.0895, 0.08792, 0.08638, 0.08488, 0.08342, 0.08199, 0.08059, 0.07923, 0.0779, 0.07661, 0.07534, 0.07411, 0.0729, 0.07172, 0.07057, 0.06945, 0.06835, 0.06727, 0.06622, 0.06519, 0.06419, 0.06321, 0.06225, 0.06131, 0.06039, 0.05948, 0.0586, 0.05774, 0.0569, 0.05607, 0.05526, 0.05447, 0.05369, 0.05293, 0.05218, 0.05145, 0.05074, 0.05003, 0.04935, 0.04867, 0.04801, 0.04736, 0.04673, 0.0461, 0.04549, 0.04489, 0.0443, 0.04372, 0.04316, 0.0426, 0.04205, 0.04152, 0.04099, 0.04047, 0.03996, 0.03946, 0.03897, 0.03849, 0.03802, 0.03756, 0.0371, 0.03665, 0.03621, 0.03578, 0.03535, 0.03493, 0.03452, 0.03412, 0.03372, 0.03333, 0.03294, 0.03256, 0.03219, 0.03183, 0.03147, 0.03111, 0.03076, 0.03042, 0.03008, 0.02975, 0.02942, 0.0291, 0.02878, 0.02847, 0.02817, 0.02786, 0.02757, 0.02727, 0.02698, 0.0267, 0.02642, 0.02614, 0.02587, 0.0256, 0.02534, 0.02508, 0.02482, 0.02457, 0.02432, 0.02408, 0.02384, 0.0236, 0.02336, 0.02313, 0.0229, 0.02268, 0.02246, 0.02224, 0.02202, 0.02181, 0.0216, 0.02139, 0.02119, 0.02099, 0.02079, 0.0206, 0.0204, 0.02021, 0.02002, 0.01984, 0.01966, 0.01947, 0.0193, 0.01912, 0.01895, 0.01878, 0.01861, 0.01844, 0.01827, 0.01811, 0.01795, 0.01779, 0.01764, 0.01748, 0.01733, 0.01718, 0.01703, 0.01688, 0.01674, 0.01659, 0.01645, 0.01631, 0.01617, 0.01604, 0.0159, 0.01577, 0.01564, 0.01551, 0.01538, 0.01525, 0.01512, 0.015, 0.01488, 0.01476, 0.01464, 0.01452, 0.0144, 0.01429, 0.01417, 0.01406, 0.01395, 0.01384, 0.01373, 0.01362, 0.01351, 0.01341, 0.0133, 0.0132, 0.0131, 0.013, 0.0129, 0.0128, 0.0127, 0.0126, 0.01251, 0.01241, 0.01232, 0.01223, 0.01213, 0.01204, 0.01195, 0.01187, 0.01178, 0.01169, 0.01161, 0.01152, 0.01144, 0.01135, 0.01127, 0.01119, 0.01111, 0.01103, 0.01095, 0.01087, 0.01079, 0.01072, 0.01064, 0.01057, 0.01049, 0.01042, 0.01035, 0.01027, 0.0102, 0.01013, 0.01006, 0.00999, 0.00992, 0.00986, 0.00979, 0.00972, 0.00966, 0.00959, 0.00953, 0.00946, 0.0094, 0.00934, 0.00927, 0.00921, 0.00915, 0.00909, 0.00903, 0.00897, 0.00891, 0.00886, 0.0088, 0.00874, 0.00868, 0.00863, 0.00857, 0.00852, 0.00846, 0.00841, 0.00836, 0.0083, 0.00825, 0.0082, 0.00815, 0.0081, 0.00804, 0.00799, 0.00794, 0.0079, 0.00785, 0.0078, 0.00775, 0.0077, 0.00765, 0.00761, 0.00756, 0.00752, 0.00747, 0.00742, 0.00738, 0.00734, 0.00729, 0.00725, 0.0072, 0.00716, 0.00712, 0.00708, 0.00704, 0.00699, 0.00695, 0.00691, 0.00687, 0.00683, 0.00679, 0.00675, 0.00671, 0.00667, 0.00664, 0.0066, 0.00656, 0.00652, 0.00649, 0.00645, 0.00641, 0.00638, 0.00634, 0.0063, 0.00627, 0.00623, 0.0062, 0.00616, 0.00613, 0.0061, 0.00606, 0.00603, 0.00599, 0.00596, 0.00593, 0.0059, 0.00586, 0.00583, 0.0058, 0.00577, 0.00574, 0.00571, 0.00568, 0.00565, 0.00562, 0.00559, 0.00556, 0.00553, 0.0055, 0.00547, 0.00544, 0.00541, 0.00538, 0.00535, 0.00533, 0.0053, 0.00527, 0.00524, 0.00522, 0.00519, 0.00516, 0.00514, 0.00511, 0.00508, 0.00506, 0.00503, 0.00501, 0.00498, 0.00495, 0.00493, 0.0049, 0.00488, 0.00486, 0.00483, 0.00481, 0.00478, 0.00476, 0.00474, 0.00471, 0.00469, 0.00467, 0.00464, 0.00462, 0.0046, 0.00457, 0.00455, 0.00453, 0.00451, 0.00449, 0.00446, 0.00444, 0.00442, 0.0044, 0.00438, 0.00436, 0.00434, 0.00432, 0.0043, 0.00427, 0.00425, 0.00423, 0.00421, 0.00419, 0.00417, 0.00415, 0.00414, 0.00412, 0.0041, 0.00408, 0.00406, 0.00404, 0.00402, 0.004, 0.00398, 0.00397, 0.00395, 0.00393, 0.00391, 0.00389, 0.00388, 0.00386, 0.00384, 0.00382, 0.00381, 0.00379, 0.00377, 0.00375, 0.00374, 0.00372, 0.0037, 0.00369, 0.00367, 0.00366, 0.00364, 0.00362, 0.00361, 0.00359, 0.00357, 0.00356, 0.00354, 0.00353, 0.00351, 0.0035, 0.00348, 0.00347, 0.00345, 0.00344, 0.00342, 0.00341, 0.00339, 0.00338, 0.00336, 0.00335, 0.00333, 0.00332, 0.00331, 0.00329, 0.00328, 0.00326, 0.00325, 0.00324, 0.00322, 0.00321, 0.0032, 0.00318, 0.00317, 0.00316, 0.00314, 0.00313, 0.00312, 0.0031, 0.00309, 0.00308, 0.00307, 0.00305, 0.00304, 0.00303, 0.00302, 0.003, 0.00299, 0.00298, 0.00297, 0.00296, 0.00294, 0.00293, 0.00292, 0.00291, 0.0029, 0.00288, 0.00287, 0.00286, 0.00285, 0.00284, 0.00283, 0.00282, 0.00281, 0.00279, 0.00278, 0.00277, 0.00276, 0.00275, 0.00274, 0.00273, 0.00272, 0.00271, 0.0027, 0.00269, 0.00268, 0.00267, 0.00266, 0.00265, 0.00263, 0.00262, 0.00261, 0.0026, 0.00259, 0.00258, 0.00257, 0.00256, 0.00256, 0.00255, 0.00254, 0.00253, 0.00252, 0.00251, 0.0025, 0.00249, 0.00248, 0.00247, 0.00246, 0.00245, 0.00244, 0.00243, 0.00242, 0.00241, 0.00241, 0.0024, 0.00239, 0.00238, 0.00237, 0.00236, 0.00235, 0.00234, 0.00234, 0.00233, 0.00232, 0.00231, 0.0023, 0.00229, 0.00229, 0.00228, 0.00227, 0.00226, 0.00225, 0.00224, 0.00224, 0.00223, 0.00222, 0.00221, 0.0022, 0.0022, 0.00219, 0.00218, 0.00217, 0.00217, 0.00216, 0.00215, 0.00214, 0.00214, 0.00213, 0.00212, 0.00211, 0.00211, 0.0021, 0.00209, 0.00208, 0.00208, 0.00207, 0.00206, 0.00205, 0.00205, 0.00204, 0.00203, 0.00203, 0.00202, 0.00201, 0.00201, 0.002, 0.00199, 0.00199, 0.00198, 0.00197, 0.00197, 0.00196, 0.00195, 0.00195, 0.00194, 0.00193, 0.00193, 0.00192, 0.00191, 0.00191, 0.0019, 0.00189, 0.00189, 0.00188, 0.00187, 0.00187, 0.00186, 0.00186, 0.00185, 0.00184, 0.00184, 0.00183, 0.00183, 0.00182, 0.00181, 0.00181, 0.0018, 0.0018, 0.00179, 0.00178, 0.00178, 0.00177, 0.00177, 0.00176, 0.00176, 0.00175, 0.00174, 0.00174, 0.00173, 0.00173, 0.00172, 0.00172, 0.00171, 0.00171, 0.0017, 0.00169, 0.00169, 0.00168, 0.00168, 0.00167, 0.00167, 0.00166, 0.00166, 0.00165, 0.00165, 0.00164, 0.00164, 0.00163, 0.00163, 0.00162, 0.00162, 0.00161, 0.00161, 0.0016, 0.0016, 0.00159, 0.00159, 0.00158, 0.00158, 0.00157, 0.00157, 0.00156, 0.00156, 0.00155, 0.00155, 0.00154, 0.00154, 0.00153, 0.00153, 0.00152, 0.00152, 0.00152, 0.00151, 0.00151, 0.0015, 0.0015, 0.00149, 0.00149, 0.00148, 0.00148, 0.00147, 0.00147, 0.00147, 0.00146, 0.00146, 0.00145, 0.00145, 0.00144, 0.00144, 0.00144, 0.00143, 0.00143, 0.00142, 0.00142, 0.00141, 0.00141, 0.00141, 0.0014, 0.0014, 0.00139, 0.00139, 0.00139, 0.00138, 0.00138, 0.00137, 0.00137, 0.00137, 0.00136, 0.00136, 0.00135, 0.00135, 0.00135, 0.00134, 0.00134, 0.00133, 0.00133, 0.00133, 0.00132, 0.00132, 0.00132, 0.00131, 0.00131, 0.0013, 0.0013, 0.0013, 0.00129, 0.00129, 0.00129, 0.00128, 0.00128, 0.00128, 0.00127, 0.00127, 0.00126, 0.00126, 0.00126, 0.00125, 0.00125, 0.00125, 0.00124, 0.00124, 0.00124, 0.00123, 0.00123, 0.00123, 0.00122, 0.00122, 0.00122, 0.00121, 0.00121, 0.00121, 0.0012, 0.0012, 0.0012, 0.00119, 0.00119, 0.00119, 0.00118, 0.00118, 0.00118, 0.00117, 0.00117, 0.00117, 0.00116, 0.00116, 0.00116, 0.00115, 0.00115, 0.00115, 0.00115, 0.00114, 0.00114, 0.00114, 0.00113, 0.00113, 0.00113, 0.00112, 0.00112, 0.00112, 0.00112, 0.00111, 0.00111, 0.00111, 0.0011, 0.0011, 0.0011, 0.00109, 0.00109, 0.00109, 0.00109, 0.00108, 0.00108, 0.00108, 0.00107, 0.00107, 0.00107, 0.00107, 0.00106, 0.00106, 0.00106, 0.00106, 0.00105, 0.00105, 0.00105, 0.00104, 0.00104, 0.00104, 0.00104, 0.00103, 0.00103, 0.00103, 0.00103, 0.00102, 0.00102, 0.00102, 0.00102, 0.00101, 0.00101, 0.00101, 0.00101, 0.001, 0.001, 0.001, 0.00099, 0.00099, 0.00099, 0.00099, 0.00098, 0.00098, 0.00098, 0.00098, 0.00098, 0.00097, 0.00097, 0.00097, 0.00097, 0.00096, 0.00096, 0.00096, 0.00096, 0.00095, 0.00095, 0.00095, 0.00095, 0.00094, 0.00094, 0.00094, 0.00094, 0.00093, 0.00093, 0.00093, 0.00093, 0.00093, 0.00092, 0.00092, 0.00092, 0.00092, 0.00091, 0.00091, 0.00091, 0.00091, 0.00091, 0.0009, 0.0009, 0.0009, 0.0009, 0.00089, 0.00089, 0.00089, 0.00089, 0.00089, 0.00088, 0.00088, 0.00088, 0.00088, 0.00088, 0.00087, 0.00087, 0.00087, 0.00087, 0.00087, 0.00086, 0.00086, 0.00086, 0.00086, 0.00085, 0.00085, 0.00085, 0.00085, 0.00085, 0.00084, 0.00084, 0.00084, 0.00084, 0.00084, 0.00084, 0.00083, 0.00083, 0.00083, 0.00083, 0.00083, 0.00082, 0.00082, 0.00082, 0.00082, 0.00082, 0.00081, 0.00081, 0.00081, 0.00081, 0.00081, 0.0008, 0.0008, 0.0008, 0.0008, 0.0008, 0.0008, 0.00079, 0.00079, 0.00079, 0.00079, 0.00079, 0.00078, 0.00078, 0.00078, 0.00078, 0.00078, 0.00078, 0.00077, 0.00077, 0.00077, 0.00077, 0.00077, 0.00077, 0.00076, 0.00076, 0.00076, 0.00076, 0.00076, 0.00075, 0.00075, 0.00075, 0.00075, 0.00075, 0.00075, 0.00074, 0.00074, 0.00074, 0.00074, 0.00074, 0.00074, 0.00073, 0.00073, 0.00073, 0.00073, 0.00073, 0.00073, 0.00073, 0.00072, 0.00072, 0.00072, 0.00072, 0.00072, 0.00072, 0.00071, 0.00071, 0.00071, 0.00071, 0.00071, 0.00071, 0.0007, 0.0007, 0.0007, 0.0007, 0.0007, 0.0007, 0.0007, 0.00069, 0.00069, 0.00069, 0.00069, 0.00069, 0.00069, 0.00069, 0.00068, 0.00068, 0.00068, 0.00068, 0.00068, 0.00068, 0.00068, 0.00067, 0.00067, 0.00067, 0.00067, 0.00067, 0.00067, 0.00067, 0.00066, 0.00066, 0.00066, 0.00066, 0.00066, 0.00066, 0.00066, 0.00065, 0.00065, 0.00065, 0.00065, 0.00065, 0.00065, 0.00065, 0.00064, 0.00064, 0.00064, 0.00064, 0.00064, 0.00064, 0.00064, 0.00064, 0.00063, 0.00063, 0.00063, 0.00063, 0.00063, 0.00063, 0.00063, 0.00062, 0.00062, 0.00062, 0.00062, 0.00062, 0.00062, 0.00062, 0.00062, 0.00061, 0.00061, 0.00061, 0.00061, 0.00061, 0.00061, 0.00061, 0.00061, 0.0006, 0.0006, 0.0006, 0.0006, 0.0006, 0.0006, 0.0006, 0.0006, 0.00059, 0.00059, 0.00059, 0.00059, 0.00059, 0.00059, 0.00059, 0.00059, 0.00059, 0.00058, 0.00058, 0.00058, 0.00058, 0.00058, 0.00058, 0.00058, 0.00058, 0.00057, 0.00057, 0.00057, 0.00057, 0.00057, 0.00057, 0.00057, 0.00057, 0.00057, 0.00056, 0.00056, 0.00056, 0.00056, 0.00056, 0.00056, 0.00056, 0.00056, 0.00056, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00055, 0.00054, 0.00054, 0.00054, 0.00054, 0.00054, 0.00054, 0.00054, 0.00054, 0.00054, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00053, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00052, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.00051, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.0005, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00049, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00048, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00047, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00046, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00045, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00044, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00043, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00042, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.00041, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.0004, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00039, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00038, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00037, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00036, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00035, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00034, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00033, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032, 0.00032]


def func(x, y):
    d, x_low, N_add = [], 0.01, 0.
    # For each upper x limit
    for x_up, N in zip(*[x, y]):
        # Number of elements in this range
        N += N_add
        # If the number of elements is < 1., combine with the next segment
        if N < 1.:
            N_add = N
        else:
            # Generate N random elements in this range
            d.extend(np.random.uniform(x_low, x_up, int(round(N))))
            # Reset the number of elements and move the lower x limit.
            N_add, x_low = 0., x_up

    return np.asarray(d)




Aucun commentaire:

Enregistrer un commentaire