can someone explain me how to slice a numpy.array at runtime?
I don't know the rank (number of dimensions) at 'coding time'.
A minimal example:
import numpy as np
a = np.arange(16).reshape(4,4) # 2D matrix
targetsize = [2,3] # desired shape
b_correct = dynSlicing(a, targetsize)
b_wrong = np.resize(a, targetsize)
print a
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
print b_correct
[[0 1 2]
[4 5 6]]
print b_wrong
[[0 1 2]
[3 4 5]]
And my ugly dynSlicing():
def dynSlicing(data, targetsize):
ndims = len(targetsize)
if(ndims==1):
return data[:targetsize[0]],
elif(ndims==2):
return data[:targetsize[0], :targetsize[1]]
elif(ndims==3):
return data[:targetsize[0], :targetsize[1], :targetsize[2]]
elif(ndims==4):
return data[:targetsize[0], :targetsize[1], :targetsize[2], :targetsize[3]]
Resize() will not do the job since it flats the array before dropping elements.
Thanks,
Tebas
Passing a tuple of slice objects does the job:
def dynSlicing(data, targetsize):
return data[tuple(slice(x) for x in targetsize)]
Simple solution:
b = a[tuple(map(slice,targetsize))]
You can directly 'change' it. This is due to the nature of arrays only allowing backdrop.
Instead you can copy a section, or even better create a view of the desired shape:
Link
Related
I have a numpy array 'arr' of shape (100000,). I need to create a numpy matrix 'res_matrix' of shape 100000X100000 such that
for i in range(res_matrix.shape[0]):
for j in range(res_matrix.shape[1]):
res_matrix[i][j]= arr[i]*arr[j]
Sample input/output
arr=[1 2 4]
Output:
res_matrix:
[[1 2 4]
[2 4 18]
[4 8 16]]
Is there way to do vectorize this operation, to reduce the computation time of calculating 00000X100000 in loop?
There are a few ways you can get an outer multiplication.
arr = np.array([1,2,4])
#Using Multiply outer
print(np.multiply.outer(arr, arr)) #As suggested by Warren
#Using broadcasting
print(arr[:,None] * arr[None,:]) #(3,1) * (1,3)
[[ 1 2 4]
[ 2 4 8]
[ 4 8 16]]
[[ 1 2 4]
[ 2 4 8]
[ 4 8 16]]
Note, the output is still a very large matrix for storing in memory. Depending on what you need it for, I would advise considering something like a generator function. Let me know how you are going to use this matrix and I could suggest more memory efficient methods.
I have created numpy array named a, then created another array b by view of a. Ex. b=a.view().
However, b.base is a is giving False instead of True. Please help.
a=np.arange(6).reshape(2,3)
b=a.view()
print(b.base is a) # Expected True, actual was False
Because it is a view of the original array which is returned by numpy.arange(6)
import numpy as np
a = np.arange(6)
b = a.reshape(2,3)
c = b.view()
print(c.base is a, b.base is a)
If you will use print statements,You will be very clear about this:-
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
b=a.view()
print(b.base)
The outputs of the print statements will look like
[[0 1 2]
[3 4 5]]
[0 1 2 3 4 5]
You can clearly see the difference.To make the output True you can use this:-
import numpy as np
a=np.arange(6)
newa=a.reshape(2,3)
print(a)
b=newa.view()
print(b.base)
print(b.base is a)
The Corresponding output will be:-
[0 1 2 3 4 5]
[0 1 2 3 4 5]
True
I want to reorder the coordinate value based on the euclidean distance .
For example I have coordinates:
1 2
2 1
1 3
1 9
6 9
3 5
6 8
4 5
7 9
I have got euclidean distance of first coordinate with other coordinate:
With the following code:
with open("../data comparision project/testfile.txt") as f:
# for splitting the text file into to lists of list
my_list = [[x for x in line.strip().split(' ')] for line in f
index = 0
# empty list to store distances.
euclidean_distance_list = []
for list_of_item in my_list:
plot1=my_list[0]
plot2=my_list[index]
euclidean_distance=math.sqrt((float(plot1[0])-float(plot2[0]))**2 + (float(plot1[1])-float(plot2[1]))**2)
index=index+1
# Out of for loop
sorted_list=sorted(euclidean_distance_list)
print(sorted_list)
This generates the following output:
[0.0, 1.0, 1.4142135623730951, 3.605551275463989, 4.242640687119285, 7.0, 7.810249675906654, 8.602325267042627, 9.219544457292887]
Now I want to reorder the original coordinate value based on the these distances such that it will be:
1 2
1 3
1 9
2 1
3 5
4 5
6 8
6 9
7 9
Can anyone help me with python code.I have caluclated distance but unable to get list with sorted coordinate vlaues.
You want to sort the list based on a custom comparator.
Check out the key optional argument to the sort function. You can supply a custom comparator as key.
https://docs.python.org/3/howto/sorting.html
To fill in a bit more detail - supposing that you already wrote the function:
def euclidean_distance(a, b):
# does the math and gives the distance between coordinates a and b.
# If you got the values some other way - better reorganize the code
# first so that you have a function like this :)
We can use functools.partial to make a function for distances from a given point:
distance_from_a = functools.partial(euclidean_distance, points[0])
and then the rest of the logic is built into Python's native sorting functionality:
sorted(points, key=distance_from_a)
You can perform a custom sort by doing something like this assuming you are using numpy:
import numpy as np
def euclidian_distance(a, b):
return np.linalg.norm(a - b)
coords = np.array([[1,2],
[2,1],
[1,3],
[1,9],
[6,9],
[3,5],
[6,8],
[4,5],
[7,9]])
coords = sorted(coords, key=lambda point: euclidian_distance(point, coords[0]))
print(np.matrix(coords)) # matrix is only for formatting for readability purposes
Output:
[[1 2]
[1 3]
[2 1]
[3 5]
[4 5]
[1 9]
[6 8]
[6 9]
[7 9]]
To explain why the above output is different from the OP's. It's because the OP's example output is not actually ordered by distance like they described they wanted.
I have an array :
a = np.array([1,2,3,4,5,6,7,8])
The array may be reshaped to a = np.array([[1,2,3,4],[5,6,7,8]]), whatever is more convenient.
Now, I have an array :
b = np.array([[11,22,33,44], [55,66,77,88]])
I want to replace to each of these elements the corresponding elements from a.
The a array will always hold as many elements as b has.
So, array b will be :
[1,2,3,4], [5,6,7,8]
Note, that I must keep each b subarray dimension to (4,). I don't want to change it.So, the idx will take values from 0 to 3.I want to make a fit to every four values.
I am struggling with reshape, split,mask ..etc and I can't figure a way to do it.
import numpy as np
#a = np.array([[1,2,3,4],[5,6,7,8]])
a = np.array([1,2,3,4,5,6,7,8])
b = np.array([[11,22,33,44], [55,66,77,88]])
for arr in b:
for idx, x in enumerate(arr):
replace every arr[idx] with corresponding a value
For your current case, what you want is probably:
b, c = list(a.reshape(2, -1))
This isn't the cleanest, but it is a one-liner. Turn your 1D array into a 2D array with with the first dimension as 2 with reshape(2, -1), then list splits it along the first dimension so you can directly assign them to b, c
You can also do it with the specialty function numpy.split
b, c = np.split(a, 2)
EDIT: Based on accepted solution, vectorized way to do this is
b = a.reshape(b.shape)
The following worked for me:
i = 0
for arr in b:
for idx, x in enumerate(arr):
arr[idx] = a[i]
print(arr[idx])
i += 1
Output (arr[idx]): 1 2 3 4 5 6 7 8
If you type print(b) it'll output [[1 2 3 4] [5 6 7 8]]
b = a[:len(a)//2]
c = a[len(a)//2:]
Well, I'm quite new to Python but this worked for me:
for i in range (0, len(a)//2):
b[i] = a[i]
for i in range (len(a)//2,len(a)):
c[i-4] = a[i]
by printing the 3 arrays I have the following output:
[1 2 3 4 5 6 7 8]
[1 2 3 4]
[5 6 7 8]
But I would go for Daniel's solution (the split one): 1 liner, using numpy API, ...
While studying the NumPy package of Python, I tried the following code segment
import numpy as np
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
v = np.array([1,0,1])
y = np.empty_like(x)
print(y)
for i in range(4):
y[i,:] = x[i,:]+v
print "......."
print(y)
However, the first print(y) gives the output such as following, instead of all zero array. On the other side, the second print(y)generates the correct result as expected. I would like to know why.
[[ 72 0 0]
[ 0 2676 1346720256]
[1599357253 1950699087 10]
[1346524499 1163154497 242503250]]
.......
[[ 2 2 4]
[ 5 5 7]
[ 8 8 10]
[11 11 13]]
You want zeros_like. empty_like gives an array filled with who-knows-what, so it doesn't have to spend time filling it with zeros.