Let say I have 2 arrays like this
array_1 = [2,4,5,1,4]
array_2 = [9,5,6,7, 4]
If I want to perform operations on each elements then I would proceed as below
import numpy as np
Res = [np.nan] * (len(array_1) * len(array_2))
for i in range(len(array_1)):
for j in range(len(array_2)):
some_cal = i+j
Res[i + j * len(array_1)] = some_cal
However my actual calculation is little different.
Let say, the anchor element of 1st array is 5 and that for second array is 7. So I want to perform calculations only on elements as highlighted below
Can you please help with some suggestions how can I modify my earlier loop to efficiently perform calculations only on elements as highlighted combination?
Thanks for your time.
Related
I am trying to write a code where i have a list of vectors and Ι have to find the angle between every vector and the rest of them.(I am working on mediapipe's hand landmarks).
My code so far is this one:
vectors = [thumb_cmc_vec, thumb_mcp_vec, thumb_ip_vec, thumb_tip_vec, index_mcp_vec, index_pip_vec,
index_dip_vec, index_tip_vec, middle_mcp_vec, middle_pip_vec, middle_dip_vec, middle_tip_vec,
ring_mcp_vec, ring_pip_vec, ring_dip_vec, ring_tip_vec, pinky_mcp_vec, pinky_pip_vec,
pinky_dip_vec, pinky_tip_vec]
for vector in vectors:
next_vector = vector + 1
print(vector)
for next_vector in vectors:
print(next_vector)
M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
ES = np.dot(vector, next_vector)
th = math.acos(ES / M)
list.append(th)
print(list)
where M = the multiplication of the norms of the current sets of vectors, ES = the
scalar product of the vectors and th = the angle of the vectors.
My problem is that the variable next_vector always starts the for loop from the first vector of the list even though I want it to start from the previous loop's next vector in order not to have duplicate results. Also when both of the loops are on the 3rd vector (thumb_ip_vec) I am getting this error
th = math.acos(ES / M)
ValueError: math domain error . Is there any way to solve this? Thank you!
I think you can iterate through the list indices (using range(len(vectors) - 1)) and access the elements through their indices instead of looping through each element
for i in range(len(vectors) - 1):
# Iterate from 0 to len(vectors) -1
vector = vectors[i]
for j in range(i + 1, len(vectors)):
# Iterate from index i + 1 to len(vectors)
next_vector = vectors[j]
M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
ES = np.dot(vector, next_vector)
th = math.acos(ES / M)
list.append(th)
print(list)
The efficient solution here is to iterate over combinations of vectors:
from itertools import combinations # At top of file
for vector, next_vector in itertools.combinations(vectors, 2):
M = (np.linalg.norm(vector) * np.linalg.norm(next_vector))
ES = np.dot(vector, next_vector)
th = math.acos(ES / M)
list.append(th)
It's significantly faster than looping over indices and indexing, reduces the level of loop nesting, and makes it more clear what you're trying to do (working with every unique pairing of the input).
I'm not sure I understand your question, but consider using ranges instead.
Ranges allow you to iterate, but without calling the exact value only, but by calling it's address.
Which means you can manipulate that index to access neighboring values.
for i in range(len(iterables)-1):
ii = i+1
initial_value = iterables[i]
next_value = iterables[ii]
for ii in range(len(iterables)):
# do_rest_of_code
Sort of like the mailman, you can reach someone's neighbor without knowing the neighbor's address.
The structure above generally works, but you will need to tweak it to meet your needs.
I am trying to make the transition from excel to python, but run in some troubles, with summing every element within an one dimensional array.
In excel this can be easily done, as in the attached image.
From excel I can clearly see the mathematical pattern for achieving this. My approach was to create a for loop, by indexing the array A.
This is my code:
import numpy as np
A = np.array([0.520094,0.850895E-1,-0.108374e1])
B = np.array([0]) #initialize array
B[0] = A[0]
A is equivalent to column A in excel & similarly B
Using a for loop to sum every element/row:
for i in range(len(A)):
i = i+1
B.append([B[i-1]+A[i]])
print(B)
This strategy doesn't work and keep getting erros. Any suggestion as to how I could make this work or is there a more elegant way of doing this?
Just use np.cumsum:
import numpy as np
A = np.array([0.520094,0.850895E-1,-0.108374e1])
cumsum = np.cumsum(A)
print(cumsum)
Output:
[ 0.520094 0.6051835 -0.4785565]
A manual approach would look like this:
A = np.array([0.520094,0.850895E-1,-0.108374e1])
B = [] # Create B as a list and not a numpy array, because it's faster to append
for i in range(len(A)):
cumulated = A[i]
if i > 0:
cumulated += B[i-1]
B.append(cumulated)
B = np.array(B) # Convert B from list to a numpy array
I have what I'm sure is a very simple problem to solve but I can't seem to get it right and have not been able to search for an answer, likely because I am using the wrong vocabulary, etc.
My goal is to have an array, called array_1, which has different 'test cases'. For each of the elements in that array, I want to run a Monte Carlo, with the current element being the input to a function. I would like to get the mean of all of the results (num_samples) and store that into another array, which will be an array of the 'means' to be easily visualized. Hard coding for each of the conditions is easy but I am looking for a more automated method. Any help would be appreciated. What I'm currently working with is below:
import numpy as np
num_samples = 5
array_1 = ([1,2,3])
array_2 = np.zeros(num_samples)
array_3 = ([])
def func_add(a, b):
return a + b + 2
#def func_append(c):
for j in array_1:
for i in range(num_samples):
r = np.random.randint(1,2)
array_2[i] = func_add( j, r)
c = np.mean(array_2) #this value I want to put in a new array to have an 'array of means'
#print(b)
array_3 = np.append(array_3, c)
print(array_2)
print(np.mean(array_2))
print(c)
print(array_3)
Which returns:
[6. 6. 6. 6. 6.]
6.0
6.0
[4. 5. 6.]
EDIT 2: The results for array_3 seem to make sense but now I'm curious as to why array_2 only contains 6's. In the first case of the loops, j = 1 and r = 1, so the function should return 4 and place that in index 1 for array_2, or do they all get overwritten by the last case of the for loop, which also would make sense I think.
Thank you in advance.
EDIT: I think the problem is that maybe that I'm pulling the value from array_1 but I want to put the mean from the processing into the first index of some array(meaning I might have to create a third array to hold those values?)
Outside the loop, you can instantiate c as an empty numpy array. Inside the for loop, you append the mean to the end of c:
np.append(c, np.mean(array_2))
Thus, the array c grows with each iteration until it contains all results.
I want to know how to code an efficient index over a numpy array. For the moment, I go over the array elements using repeated additions. For example, I have to make some loops over an array A like this:
import numpy as np
A = np.arange(0,100)
M = 10
for i in range(A.shape[0]-M):
B = []
for j in range(M):
value = A[i+j]
B.append(value)
Is there a way for me to get the values without repeatedly doing the i+j addition?
I have a numpy array and I want to add n elements with the same value until the length of the array reaches 100.
For example
my_array = numpy.array([3, 4, 5])
Note that I do not know the length of the array beforehand. It may be anything 3 <= x <= 100
I want to add (100 - x) more elements, all with the value 9.
How can I do it?
There are two ways to approach this: concatenating arrays or assigning them.
You can use np.concatenate and generate an appropriately sized array:
my_array = # as you defined it
remainder = [9] * (100 - len(my_array))
remainder = np.array(remainder)
a100 = np.concatenate((my_array, remainder))
Alternatively, you can construct a np.full array, and then overwrite some of the values using slice notation:
a100 = numpy.full(100, 9)
my_array = # as you defined it
a100[0:len(my_array)] = my_array
It's important to remember with numpy arrays, you can't add elements like you can with lists. So adding numbers to an array is not really the best thing to do.
Far better is to start with an array, and replace the elements with new data as it comes in. For example:
import numpy as np
MY_SPECIAL_NUMBER = 100
my_array = np.array[3, 4, 5]
my_new_array = np.ones(100) * MY_SPECIAL_NUMBER
my_new_array[:my_array.size] = my_array
my_new_array is now what you want.
If you "cannot" know the size of your mysterious array:
fillvalue=9
padding=numpy.ones(100)*fillvalue
newarray=numpy.append(myarray, padding)
newarray=newarray[:100]