3
\$\begingroup\$

I was wondering what would be the efficient way to determine the value of a position on an array based on its nearest datapoint known value in Python?

Problem description:

There are datapoints in an array which are 1000 units apart and their values are known (see the figure). However, there are datapoints which fall between the known datapoints and their values should be determined based on their nearest known datapoint.

For instance, following the figure, the value of the datapoint at position 124200 should be set to 435 and the value of the datapoint at position 124850 should be set to 380.

determining the value of a position on an array based on its nearestdatapoint known value

At the moment, I am doing it like this:

# 'values' is an array which has the values for the known datapoints 
# 'position' is an array that has the datapoints which their values should be determined
# 'step' keeps the number of units in between two datapoints with known values
# 'n' is a list which keeps the extracted values

for pos in positions:
    if pos % step <= 500:
        idx = (( pos - (pos % step)) / step) - 1
        n.append(values[idx])
    else:       #pos % step > 500:
        idx = (( pos + (step - (pos % step))) / step)  - 1
       n.append(values[idx])

I was also considering implementing the logic with addition and subtraction operations instead of modulo and division operations, but after some discussion with a friend, we came up with the conclusion that modern processors in doing divisions and multiplication are as fast as doing addition and subtraction, so I ruled that option out.

\$\endgroup\$
1
  • \$\begingroup\$ It doesn't matter whether you use addition, subtraction, multiplication, division or modulo if your code isn't performance critical. More importantly is the clarity of your code. :) \$\endgroup\$
    – wei2912
    Commented Oct 2, 2014 at 7:02

2 Answers 2

2
\$\begingroup\$

This is an application of rounding.

idx = int(round(float(pos) / step)) - 1

Note, however, that the result in case pos is exactly halfway into a step is different from your code, and also differs between Python versions.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for your answer. I also came up with the following answer myself: indices = np.around(positions / step).astype(int) \$\endgroup\$
    – Dataman
    Commented Sep 23, 2014 at 13:41
1
\$\begingroup\$

I think that the following code answers my question:

import numpy as np
indices = np.around(np.array(positions) / step).astype(int)
for idx in indices:
    n.append(values[idx])

EDIT

I came up with the idea that the above code can become even more efficient by removing the for loop as below:

import numpy as np
indices = np.around(np.array(positions) / step).astype(int)
n = values[indices]
\$\endgroup\$
1
  • \$\begingroup\$ Consider replacing idx with i. \$\endgroup\$
    – wei2912
    Commented Oct 2, 2014 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.