I have two arrays y=[0,1,1], x=[0,0,4,10,5]and a Index-array with integers that has the indices of the non-zero entrys from x I_x=[2,3,4].
And idealy I would want something like y[2]=0, y[3]=1, y[4]=1
Is there any way to do that for the general case.
I'm happy to answer further questions because I don't think this question is asked well enough.
edit:
def function(x,y):
solution = 0
for i in I:
solution = x[i] + y[i]
return solution
This is an example what I want to do, the problem is i is from I so y would be out of bounds, what I want to know is there any way to solve this problem.
Your question is still a bit unclear, but I think you are trying to produce an array which contains the sum of the nonzero elements in x with the elements in y in those positions, and you are trying to adjust it so that Ix will not be out of bounds for y. The script below does just that:
import numpy as np
def uneven_add(a, b):
return a[np.nonzero(a)] + np.hstack((b, np.zeros((a.size - b.size))))[np.nonzero(a)]
if __name__ == '__main__':
x = np.array([0,0,4,10,5])
y = np.array([0,1,1])
print(uneven_add(x,y))
Related
I am learning how to code and wondered how to take the mean without using a builtin function (I know these are optimized and they should be used in real life, this is more of a thought experiment for myself).
For example, this works for vectors:
def take_mean(arr):
sum = 0
for i in arr:
sum += i
mean = sum/np.size(arr)
return mean
But, of course, if I try to pass a matrix, it already fails. Clearly, I can change the code to work for matrices by doing:
def take_mean(arr):
sum = 0
for i in arr:
for j in i:
sum += i
mean = sum/np.size(arr)
return mean
And this fails for vectors and any >=3 dimensional arrays.
So I'm wondering how I can sum over a n-dimensional array without using any built-in functions. Any tips on how to achieve this?
You can use a combination of recursion and loop to achieve your objective without using any of numpy's methods.
import numpy as np
def find_mean_of_arrays(array):
sum = 0
for element in array:
if type(element) == type(np.array([1])):
sum += find_mean_of_arrays(element)
else:
sum += element
return sum/len(array)
Recursion is a powerful tool and it makes code more elegant and readable. This is yet another example
Unless you need to mean across a specific axis, the shape of the array does not matter to compute the mean. Making your first solution possible.
def take_mean(arr):
sum = 0
for i in arr.reshape(-1): # or arr.flatten()
sum += i
mean = sum/np.size(arr)
return mean
I have two arrays:
X = np.linspace(0,100,101) and Y = np.linspace(0,100,15). How to make the values of one array be rounded to the values of the other array. that is, I finally have an array of size 101 but the values of the array X came close to the nearest values of the array Y.
Like this?
Y[np.absolute(X[:,np.newaxis]-Y).argmin(axis=1)]
The simplest way is to use X array to produse Y array. Like this:
Y = X[::len(X)//15]
But it'll give you a little biased numbers.
For this particular case you also can use simple round function:
Y = np.array(list(map(round, Y)))
In general, you can solve this by searching for the minimal difference between elements in arrays:
Y = X[[abs(X-i).argmin() for i in Y]]
I am working on some molecular dynamics using Python, and the arrays tend to get pretty large. It would be helpful to have a quick check to see if certain vectors appear in the arrays.
After searching for way to do this, I was surprised to see this question doesn't seem to come up.
In particular,
if I have something like
import numpy as np
y = [[1,2,3], [1,3,2]]
x = np.array([[1,2,3],[3,2,1],[2,3,1],[10,5,6]])
and I want to see if the specific vectors from y are present in x (not just the elements), how would I do so?
Using something like
for i in y:
if i in x:
print(i)
will simply return every y array vector that contains at least one element of i.
Thoughts?
If you want to check if ALL vectors in y are present in the array, you could try:
import numpy as np
y = [[1,2,3], [1,3,2]]
x = np.array([[1,2,3],[3,2,1],[2,3,1],[10,5,6]])
all(True if i in x else False for i in y)
# True
You don't explicitly give your expected output, but I infer that you want to see only [1, 2, 3] as the output from this program.
You get that output if you make x merely another list, rather than a NumPy array.
The best strategy will depend on sizes and numbers. A quick solution is
[np.where(np.all(x==row, axis=-1))[0] for row in y]
# [array([0]), array([], dtype=int64)]
The result list gives for each row in y a possibly empty array of positions in x where the row occurs.
I have the following code
l = len(time) #time is a 300 element list
ll = len(sample) #sample has 3 sublists each with 300 elements
w, h = ll, l
Matrix = [[0 for x in range(w)] for y in range(h)]
for n in range(0,l):
for m in range(0,ll):
x=sample[m]
Matrix[m][n]= x
When I run the code to fill the matrix I get an error message saying "list index out of range" I put in a print statement to see where the error happens and when m=0 and n=3 the matrix goes out of index.
from what I understand on the fourth line of the code I initialize a 3X300 matrix so why does it go out of index at 0X3 ?
You need to change Matrix[m][n]= x to Matrix[n][m]= x
The indexing of nested lists happens from the outside in. So for your code, you'll probably want:
Matrix[n][m] = x
If you prefer the other order, you can build the matrix differently (swap w and h in the list comprehensions).
Note that if you're going to be doing mathematical operations with this matrix, you may want to be using numpy arrays instead of Python lists. They're almost certainly going to be much more efficient at doing math operations than anything you can write yourself in pure Python.
Note that indexing in nested lists in Python happens from outside in, and so you'll have to change the order in which you index into your array, as follows:
Matrix[n][m] = x
For mathematical operations and matrix manipulations, using numpy two-dimensional arrays, is almost always a better choice. You can read more about them here.
Consider a 100X100 array.
i) Generate an array of several thousand random locations within such an array, e.g. (3,75) and (56, 34).
ii) Calculate how often one of your random locations falls within 15 pixels of any of the (straight) edges.
I am trying to do the above question in order to help me to learn the programming language Python, i am new to programming.
Here is what i have got so far:
from __future__ import division
from pylab import *
import math as m
from numpy import *
from random import randrange
N = 3000
coords_array = array([randrange(100) for _ in range(2 * N)]).reshape(N, 2)
This creates the array of N random locations, and no i am trying to create a loop that will append a 1 to an empty list if x>85 or y>85 or x<15 or y<15, then append a zero to the same empty list if x or y is anything else. Then i would find the sum of the list, which would be my count of how many of the random location fall within the edges.
This is the kind of thing i am trying to do:
coordinate=coords_array[x,y]
b=[]
def location(x,y):
if x>85 or y>85:
b.appnend(1)
if x<15 or y<15:
b.append(1)
else:
b.append(0)
print b
print x
But i am having trouble assigning the array as x and y variables. I want to be able assign each row of the set of random coordinates as an x,y pair so that i can use it in my loop.
But i do not know how to do it!
Please can someone show me how to do it?
Thank you
Ok, the answer to this:
But i am having trouble assigning the array as x and y variables. I
want to be able assign each row of the set of random coordinates as an
x,y pair so that i can use it in my loop
Would be this:
for pair in coords_array:
# Do something with the pair
NumPy arrays behave as regular Python sequences by letting for to iterate over their main axis, meaning pair will contain an array of (in your case) two elements: x and y. You can also do this:
for x, y in coords_array:
# Do something with the pair
NB: I think you wanted to write the function like this:
def location(x,y):
if x>85 or y>85:
b.append(1)
elif x<15 or y<15:
b.append(1)
else:
b.append(0)
or
def location(x,y):
if x>85 or y>85 or x<15 or y<15:
b.append(1)
else:
b.append(0)
or even
def location(x,y):
if not (15 <= x <= 85) or not (15 <= y <= 85):
b.append(1)
else:
b.append(0)
Otherwise, as #TokenMacGuy points out, you'd be inserting two values in certain cases.
NB: from your question I understand you want to write this code specifically to learn Python, but you could do this in a much more straightforward (and efficient) way by just using NumPy functionality
You can let numpy do the looping for you:
n = 3000
coords = np.random.randint(100, size=(n, 2))
x, y = coords.T
is_close_to_edge = (x < 15) | (x >= 85) | (y < 15) | (y >= 85)
count_close_to_edge = np.sum(is_close_to_edge)
Note that the first index of a 100 element array is 0 and the last 99, hence items within 15 positions of the edges are 0...14 and 85...99, hence the >= in the comparison. In the code above, is_close_to_edge is your list, with boolean values.