Single Line Nested For Loops in Python - python

I'm having some trouble understanding how nested single line for loops work. Here's an example:
I have this code:
NewArray = np.array([ get_position(i, size-1, t) for i in range(0, size)])
and I'm trying to rewrite this to:
for i in range(0,size):
NewArray = np.array([ get_position(i, size-1, t)])
But I'm getting different outputs, so I'm guessing there's a logic error here.
Could you point out the issue?
Thank you

It's because the first one creates a numpy array containing all your values (you create all values because you're using a list comprehension) and the second one creates a new array containing the last value each iteration (and it discards the array created in the last iteration because you reuse the same name).
You could rewrite the second one as:
lst = []
for i in range(0,size):
lst.append(get_position(i, size-1, t))
NewArray = np.array(lst)
that should give the same result as your first operation.

In the first you create an array of length size.
In the second you repeatedly (size times) create an array of length 1.

Related

Most Efficient Way To Separate Out Data from List within a List

I have a function with outputs 2 arrays, lets call them X_i, and Y_i which are two N x 1 arrays, where N is the number of points. By using multiprocessing's pool.apply_aync, I was able to parallelize this function which gave me my results in a HUGE list. The structure of the results are a list of M values, where each value is a list containing X_i and Y_i. So in summary, I have a huge list which M smaller lists containing the two arrays X_i and Y_i.
Now I have want append all the X_i's into one array called X and Y_i's called Y. What is the most efficient way to do this? I'm looking for some sort of parallel algorithm. Order does NOT matter!
So far I have just a simple for loop that separates this massive data array:
X = np.zeros((N,1))
Y = np.zeros((N,1))
for i in range(len(results))
X = np.append(results[i][0].reshape(N,1),X,axis = 1)
Y = np.append(results[i][1].reshape(N,1),Y,axis = 1)
I found this algorthim to be rather slow, so I need to speed it up! Thanks!
You should provide a simple scenario of your problem, break it down and give us a simple input, output scenario, it would help a lot, as all this variables and text make it a bit confusing.Maybe this can help;
You can unpack the lists, then grab the ones you need by index, append the list to your new empty X[] and append the other list you needed to Y[], at the end get the arrays out of the lists and merge those into your new N dimensional array or into a new list.
list = [[[1,2],[3,4]],[[4,5],[6,7]]]
sub_pre = []
flat_list = []
for sublist in list:
sub_pre.append(sublist)
for item in sublist:
flat_list.append(item)
print(list)
print(flat_list)
Thanks to #JonSG for the brilliant insight. This type of sorting algorithm can be sped up using array manipulation. Through the use of most parallels packages, a function that outputs in multiple arrays will most likely get put into a huge list. Here I have a list called results, which contains M smaller lists of two N x 1 arrays.
To unpack the main array and sort all the X_i and Y_i into their own X and Y arrays respectively, it can be done so like this.
np.shape(results) = (M, 2, N)
X = np.array(results)[:,0,:]
Y = np.array(results)[:,1,:]
This gave me an 100x speed increase!

Concatenate numpy arrays within for iterations

Within a for loop, I am extracting a Numpy array of size 10x256. I would like to concatenate all those arrays (the iteration in total are 20) and create an array of size of 200x256. I managed to do that by using a for loop within the for loop:
my_list= []
for i in range(0,20):
my_arr = process() # 10x256
for item in my_arr:
my_list.append(item)
How can I do the same thing without using the second for loop?
With single numpy.concatenate routine:
new_arr = np.concatenate([process() for i in range(20)])

Append result of iteration in python

I am pretty new to python, i am using python 3 and have some difficulties to append the result of the iteration to the array, following is my chunk of my code:
A = np.random.randn(len(meas),numx)
lengthA = np.linspace(0,len(A[0])-1,num=len(A[0]),dtype=int)
anorm = []
for j in range(0,len(lengthA)):
x_normed = A/A.max(axis=0)
anorm[:,j] = A[:,j]*x_normed[j]
Is it necessary to append the new result to empty anom ? somehow the code always tell me that the list of the indices must be integer and not tuple. Any help will be appreciated.
When assigning a value to an array at index n via the array[index] = value syntax, the argument within the square brackets must be an integer. In your situation, j is an integer but [:,j] attempts to reference multiple indices within the array.
for j in range(0,len(lengthA)):
x_normed = A/A.max(axis=0)
anorm[j] = A[:,j]*x_normed[j]
As an aside, if you want your for loop to run for as many iterations as there are elements within lengthA, then you can simply do:
for j in lengthA:
do stuff

python - how to reassign element in array with for loop

I have a numpy array of floats that I want to reassign with a different value using a for loop but PyCharm says the new variable assignment isn't being used.
If I have, say:
for i in array:
i = i * 5
It will say that i is an unused variable. What am I doing wrong?
You need to assign values to array elements. Otherwise you array will remain unchanged. There are a couple of ways.
Using your current attempt as a starting point, you can use enumerate. Given an input array:
for idx, val in enumerate(array):
array[idx] = val * 5
But this doesn't take advantage of NumPy vectorisation. You can simply use:
array *= 5
Should be:
for i in range(len(array)):
array[i] = array[i] * 5
What you did was creating a temporary variable "i", which exists only on each loop iteration, it is initialized with the value of an element from the list and then it's deleted.
A more pythonic way of doing this would be:
array = [i*5 for i in array]

Filling a list inside a for loop in python

I am trying to make a vector out of two different ones as shown in the piece of code below.
However, I get a list out of range exception on the 5th line the first time the code goes in the for loop.
What am I doing wrong?
def get_two_dimensional_vector(speeds, directions):
vector = []
for i in range(10):
if (i % 2 == 0):
vector[i/2][0] = speeds[i/2]
else :
vector[i/2 - 1/2][1] = directions[i/2 - 1/2]
You can't use a Python list this way. It's not like a C array with a
predefined length. If you want to add a new element, you have to use the
append method or something.
Aside from that, you're also using a second index, implying that the
elements of vector are themselves lists or dicts or something, before
they've even been assigned.
It looks like you want to convert speeds and directions to a
two-dimensional list. So, first, here's how to do that with a loop. Note
that I've removed the fixed-size assumption you were using, though the
code still assumes that speeds and directions are the same size.
def get_two_dimensional_vector(speeds, directions):
vector = []
for i in range(len(speeds)):
vector.append([speeds[i], directions[i]])
return vector
speeds = [1, 2, 3]
directions = [4, 5, 6]
v = get_two_dimensional_vector(speeds, directions)
print(v)
Now, the Pythonic way to do it.
print(zip(speeds, directions))

Categories

Resources