I am making a program in python and I am having an error that I cannot solve.
This is the problem:
I have a set to points in 3D space, and I am storing it in a vector(rake).
My point is to build a stream surface.
So I am appending those points to another list so that I can have all the points from the "line" before.
The rake list has this format:
[[60, 0, 50], [63, 3, 50], [66, 6, 50], [69, 9, 50], [72, 12, 50],
[75, 15, 50], [78, 18, 50], [81, 21, 50], [84, 24, 50], [87, 27, 50],
[90, 30, 50], [93, 33, 50], [96, 36, 50], [99, 39, 50], [102, 42, 50]]
Then when I append the points to the other list(points_list) is like this:
[[[60, 0, 50], [63, 3, 50], [66, 6, 50], [69, 9, 50], [72, 12, 50],
[75, 15, 50], [78, 18, 50], [81, 21, 50], [84, 24, 50], [87, 27, 50],
[90, 30, 50], [93, 33, 50], [96, 36, 50], [99, 39, 50], [102, 42, 50]]]
My point is that with the points_list I can know in witch iteration level I am dealing with, so that I could render the surface in the end.
When I try to get, for instance, one element from the points_arrays I have and index error.
this is the code:
points_arrays.append(rake)
for i in range(iterations):
for j in range(rlength):
print points_arrays[i][j][0],points_arrays[i][j][1],points_arrays[i][j][1]
When I run this part of the code I am able to get the points but in the end I get an index error. (IndexError: list index out of range)
Can anyone help me to solve this??
Your main problem is that you should use extend instead of append:
points_list.extend(rake)
This is because append adds a single object to the end of the list. In this case it means that the entire second list is appended as a single element.
append - append object to end
extend - extend list by appending elements from the iterable
You should also be aware of the following points that are not directly related to your problem:
In Python the object created when you write [1, 2, 3] is called a list, not an array.
Your print statement is wrong. The second occurrence of points_arrays[i][j][1] should be points_arrays[i][j][2]
for rake in points_list:
for point in rake:
print point[0], point[1], point[2]
If you want to use numbers as indexes:
for npoint in xrange(len(points_list))
for nrake in xrange(len(points_list[npoint]))
print points_list[npoint][nrake][0], points_list[npoint][nrake][1], points_list[npoint][nrake][2]
Related
In 2d array get the last column and compare current value with its last iterated value and if the difference is == 1 then get row indexes of both of them . I able to do it using for loop but it gets slow when array grows as there are multiple conditions next after getting indexes
x=np.array ([[79, 50, 18, 55, 35],
[46, 71, 46, 95, 80], #1
[97, 37, 71, 2, 79], #2
[80, 96, 60, 85, 72],
[ 6, 52, 63, 86, 38],
[35, 50, 13, 93, 54], #5
[69, 21, 4, 40, 53], #6
[18, 34, 91, 67, 89],
[82, 16, 16, 24, 80]])
last_column = x[:,[-1]]
for kkk in range(1,len(last_column)):
if last_column[kkk] == last_column[kkk-1] + 1 \
or last_column[kkk] == last_column[kkk-1] - 1 :
print('range',last_column[kkk],last_column[kkk-1])
ouput is -
[80]
[79]
range [79] [80]
[72]
[38]
[54]
[53]
range [53] [54]
[89]
[80]
I don't think there is a way of doing this in python that doesn't use a loop (or a function that utilizes a loop). But I would suggest something like this, it worked quite well for me:
import numpy as np
x = np.array([[79, 50, 18, 55, 35], [46, 71, 46, 95, 80], [97, 37, 71, 2, 79],[80, 96, 60, 85, 72], [ 6, 52, 63, 86, 38], [35, 50, 13, 93, 54], [69, 21, 4, 40, 53], [18, 34, 91, 67, 89], [82, 16, 16, 24, 80]])
last_column = x[:,-1]
for kkk in range(1,len(last_column)):
if abs(last_column[kkk] - last_column[kkk-1]) == 1:
print('range',last_column[kkk],last_column[kkk-1])
This performed quite well on my device in about, 0.00023s possibly less.
You can use np.diff to compute the difference between all the numbers, and select those that are 1 or -1, and use np.pad to shift the resulting mask to get the n-1 items, and finally zip them together:
diff = np.insert(np.diff(x[:, -1]), 0, 0)
ix = (diff == -1) | (diff == 1)
z = zip(x[:,-1][ix], x[:,-1][np.pad(ix, (0,1))[1:]])
for first, second in z:
print('range', first, second)
Output:
range 79 80
range 53 54
I have array A = np.ones((4,4,4)) and another array that represent the coordinates of point in array A called B, lets assume that B = [[2,2,2], [3,2,1]].
I tried to access A by array indexing like A[B], but it didn't works.
How i can do it in elegant way, that also work for B that it's have a higher dimensions like B of shape (10, 20, 3) ?
You can pass a list of coordinates, but you should transpose the list. Such that the items of the i-th dimension are passed as the i-th element in the indexing, for example with:
A[tuple(np.transpose(B))]
For a 4×4×4 matrix:
>>> A = np.arange(64).reshape(4,4,4)
>>> A
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]],
[[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]],
[[32, 33, 34, 35],
[36, 37, 38, 39],
[40, 41, 42, 43],
[44, 45, 46, 47]],
[[48, 49, 50, 51],
[52, 53, 54, 55],
[56, 57, 58, 59],
[60, 61, 62, 63]]])
we get for the given coordinates:
>>> A[tuple(np.transpose(B))]
array([42, 57])
and if we calculate these manually, we get:
>>> A[2,2,2]
42
>>> A[3,2,1]
57
Background:
A[1,2,3] is short for A[(1,2,3)] (so in a tuple). You can fetch multiple items with A[([2,3], [2,2], [2,1])] but then you thus first need to transpose the data.
Since the data is represented as [[2,2,2], [3,2,1]], we thus first need to transpose it to [[2,3], [2,2], [2,1]]. Next we wrap it in a tuple, and can use this to subscript A.
I have an array, arr, which represents n permutations of m coordinates. With each permutation, I'm attempting to calculate the total round trip distance (the problem relates to the travelling salesperson problem). To do this, I've been concatenating the first coordinate of each permutation and then calculating the round trip distance using np.linalg.norm.
array([[[40, 30],
[37, 52],
[52, 64],
[49, 49],
[20, 26]],
[[52, 64],
[49, 49],
[40, 30],
[20, 26],
[37, 52]]])
To get the round trip coordinate sequences, I have been using the following.
>>> np.array([np.concatenate((a, a[0, np.newaxis])) for a in arr])
array([[[40, 30],
[37, 52],
[52, 64],
[49, 49],
[20, 26],
[40, 30]], # First coordinate concatenated
[[52, 64],
[49, 49],
[40, 30],
[20, 26],
[37, 52],
[52, 64]]]) # First coordinate concatenated
Is there builtin NumPy functionality to achieve this?
a = np.array([[[40, 30],
[37, 52],
[52, 64],
[49, 49],
[20, 26]],
[[52, 64],
[49, 49],
[40, 30],
[20, 26],
[37, 52]]])
a = np.concatenate(a, axis=1) # merge into single array
a = np.concatenate((a,a[0,np.newaxis])) # add ending coordinates
N=2 # replace with number of merged arrays
result = np.split(a,N, axis=1) # list of arrays
I have an array of ints, they need to be grouped by 4 each. I'd also like to select them based on another criterion, start < t < stop. I tried
data[group].reshape((-1,4))[start < t < stop]
but that complains about the start < t < stop because that's hardcoded syntax. Can I somehow intersect the two arrays from start < t and t < stop?
The right way of boolean indexing for an array should be like this:
>>> import numpy as np
>>> a=np.random.randint(0,20,size=24)
>>> b=np.arange(24)
>>> b[(8<a)&(a<15)] #rather than 8<a<15
array([ 3, 5, 6, 11, 13, 16, 17, 18, 20, 21, 22, 23])
But you may not be able to reshape the resulting array into a shape of (-1,4), it is a coincidence that the resulting array here contains 3*4 elements.
EDIT, now I understand your OP better. You always reshape data[group] first, right?:
>>> b=np.arange(96)
>>> b.reshape((-1,4))[(8<a)&(a<15)]
array([[12, 13, 14, 15],
[20, 21, 22, 23],
[24, 25, 26, 27],
[44, 45, 46, 47],
[52, 53, 54, 55],
[64, 65, 66, 67],
[68, 69, 70, 71],
[72, 73, 74, 75],
[80, 81, 82, 83],
[84, 85, 86, 87],
[88, 89, 90, 91],
[92, 93, 94, 95]])
How about this?
import numpy as np
arr = np.arange(32)
t = np.arange(300, 364, 2)
start = 310
stop = 352
mask = np.logical_and(start < t, t < stop)
print mask
print arr[mask].reshape((-1,4))
I did the masking before the reshaping, not sure if that's what you wanted. The key part is probably the logical_and().
For example, if I have the following (data from Project Euler):
s = [[75],
[95, 64],
[17, 47, 82],
[18, 35, 87, 10],
[20, 4, 82, 47, 65],
[19, 1, 23, 75, 3, 34],
[88, 2, 77, 73, 7, 63, 67],
[99, 65, 4, 28, 6, 16, 70, 92],
[41, 41, 26, 56, 83, 40, 80, 70, 33],
[41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
[63, 66, 4, 68,89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
[4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]]
Why does s[1:][:-1] give me the same thing as s[1:] instead of (what I want) [s[i][:-1] for i in range(1,len(s))]. In other words, why does Python ignore my second index?
Python doesn't have 2-dimensional lists, it has lists of lists. I think the first [1:] gives everything but the first contained list, and the second [:-1] takes that result and removes the last contained list.
What you want is:
[r[:-1] for r in s[1:]]
You're misdescribing the results: s[1:][:-1] is definitely not the same as s[:1], as you erroneously say -- it is, rather, the same as s[1:-1]. Check it out!
This must necessarily hold true of any list s, no matter what its contents may be (other lists, dicts, strings, floats, unicorns, ...): s[1:] means "all but the first", then [:-1] means "all but the last", so obviously their combined effects are the same as [1:-1] which means "all but the first and last". The indexing-like syntax with a colon in the brackets is also known as slicing, and when applied to a list (of whatevers) it returns another (typically shorter) list (also of whatevers).
Thinking of s as a "jagged array" rather than what it actually is (just a list, whose items happen to also be lists -- but the type of some or all of the items obviously can't and shouldn't affect the semantics of operations on the list itself, like slicing) may be what's throwing you off; perhaps because, if the first indexing is actually an indexing and not a slicing, its results is an item of the original list -- a "whatever" (a list of ints in your case), not a list of whatevers. So if you then apply a further indexing or slicing you're doing that on one of the original sublists -- a very different matter.
#Mark's answer has already shown the canonical list-comprehension solution to do what you actually want. I think that other approaches, if you have matlab code and want the Python equivalent, might include OMPC (but I haven't tried that myself).