Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have this homework to do for my python class at Uni and I can't get my head around it. Basically I need to write a program that returns an NxN array( preferably using numpy in such a scenario:
123456
212345
321234
432123
543212
654321
I've attampted to create a simple 6x6 array for example
X = np.full((n,n),np.arange(1,+n+1))
which returns
123456
123456
123456
123456
123456
123456
But these are simply permutations of switching the last element with the first and "pushing the ones in the middle to the right but as mentioned earlier its more complex. Thanks in advance.
Can you come up with a formula for X[i,j] in terms of i and j? (I can, but this is homework!)
If so, you can do:
is, js = np.indices((n,n))
X = your_formula(is, js)
For example, if you wanted X[i,j] = i + j, you could do
is, js = np.indices((n,n))
X = is + js
Which for n=3 would give
012
123
234
If you're writing loops to solve array problems, you're usually doing it wrong. Just use an upper triangular matrix.
from scipy.linalg import circulant
import numpy as np
>>> arr = circulant(np.arange(1,7)).T
>>> np.triu(arr, 1).T + np.triu(arr)
array([[1, 2, 3, 4, 5, 6],
[2, 1, 2, 3, 4, 5],
[3, 2, 1, 2, 3, 4],
[4, 3, 2, 1, 2, 3],
[5, 4, 3, 2, 1, 2],
[6, 5, 4, 3, 2, 1]])
As this is a homework, I will not give you the complete answer, but I'll give you a tip enough to get you going.
As you have all those numbers, consider putting them into an np.array that way you could use np.reshape(verctor, [lines, columns]). Here's the link to the Numpy documentation.
This is probably not an answer that you can use for your homework, but...
In [619]: from scipy.linalg import toeplitz
In [620]: toeplitz(range(1, 7))
Out[620]:
array([[1, 2, 3, 4, 5, 6],
[2, 1, 2, 3, 4, 5],
[3, 2, 1, 2, 3, 4],
[4, 3, 2, 1, 2, 3],
[5, 4, 3, 2, 1, 2],
[6, 5, 4, 3, 2, 1]])
See the documentation for scipy.linalg.toeplitz for more information.
There are several options to do that:
Perhaps the most straightforward approach would be that of using slicings and list comprehensions
def myfunc(n):
x = range(1, n+1)
return np.asarray([x[1:i+1][::-1] + x[:n-i] for i in range(n)])
You could also use Matlab-like functions diag and transpose
def myfunc(n):
x = np.diag(np.ones(n))
for i in range(2, n+1):
d = np.diag(i*np.ones(n-i+1), i-1)
x += d + d.T
return x
Loop-based solutions - as #GoBrewers14 correctly pointed out - are inefficient for creating large arrays though. In this case you should utilize a vectorized algorithm instead. If you don't wish to employ the SciPy's toeplitz and circulant functions suggested in other answers, broadcasting is your friend.
def myfunc(n):
x = np.arange(n).reshape((1, n))
return np.abs(x - x.T) + 1
And this is what you get by running any of the implementations above:
>>> myfunc(6)
array([[1, 2, 3, 4, 5, 6],
[2, 1, 2, 3, 4, 5],
[3, 2, 1, 2, 3, 4],
[4, 3, 2, 1, 2, 3],
[5, 4, 3, 2, 1, 2],
[6, 5, 4, 3, 2, 1]])
Hope this helps
Related
for f in train.columns:
missings = train[train[f] == -1][f].count()
what does trainp[][] mean? How can this be two dimensional array if f referring to another column?
For vanilla python It is certainly very odd and poorly written code, but it could be valid in a very limited number of situations. Below are a couple examples in which it would work. I am sure there are more, but either way it is not very easy to understand and I do not recommend using it in your own code.
Note: the iterable.count() method requires 1 argument.
example 2
f = 4
train = [[1, 2, 3, 4, [0, 0, 1, 0]], [1, 2, 3, 4, [1, 0, 1, 1]], 0, 1, -1]
missings = train[train[f] == -1][f].count(1)
print(missings) # output = 3
example 1
f = 4
train = {True: [1, 2, 3, 4, [0, 0, 0, 1]], False: [1, 2, 3, 4, [1, 1, 1, 0]], 4: 1}
missing = train[train[f] == -1][f].count(1)
print(missing) # output = 3
It's looking like you are already getting values from the 2D array i-e train[train[f] == -1][f]
you can make it a 2D array by doing something like that
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
or
arr = [[12, 13, 5, 4], [14, 8,11], [12, 10, 12, 6], [15,17,9,0]]
I have a 3D array that I like to repeat 4 times.
Achieved via a mixture of Numpy and Python methods:
>>> z = np.arange(9).reshape(3,3)
>>> z
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> z2 = []
>>> for i in range(4):
z2.append(z)
>>> z2
[array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]), array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]), array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]), array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])]
>>> z2 = np.array(z2)
>>> z2
array([[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]])
Achieved via Pure NumPy:
>>> z2 = np.repeat(z[np.newaxis,...], 4, axis=0)
>>> z2
array([[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]])
Are the elements created by numpy.repeat() views of the original numpy.array() or unique elements?
If the latter, is there an equivalent NumPy functions that can create views of the original array the same way as numpy.repeat()?
I think such an ability can help reduce the buffer space of z2 in the event size of z is large and when there are many repeats of z involved.
A follow-up on one of #FrankYellin answer:
>>> z = np.arange(9).reshape(3,3)
>>> z
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> z2 = np.repeat(z[np.newaxis,...], 1_000_000_000, axis=0)
>>> z2.nbytes
72000000000
>>> y2 = np.broadcast_to(z, (1_000_000_000, 3, 3))
>>> y2.nbytes
72000000000
The nbytes from using np.broadcast_to() is the same as np.repeat(). This is surprising given that the former returns a readonly view on the original z array with the given shape. Having said this, I did notice that np.broadcast_to() created the y2 array instantaneously, while the creation of z2 via np.repeat() took abt 40 seconds to complete. Hence,np.broadcast_to() yielded significantly faster performance.
If you want a writable version, it is doable, but it's really ugly.
If you want a read-only version, np.broadcast_to(z, (4, 3, 3)) should be all you need.
Now the ugly writable version. Be careful. You can corrupt memory if you mess the arguments up.
> z.shape
(3, 3)
> z.strides
(24, 8)
from numpy.lib.stride_tricks import as_strided
z2 = as_strided(z, shape=(4, 3, 3), strides=(0, 24, 8))
and you end up with:
>>> z2[1, 1, 1]
4
>>> z2[1, 1, 1] = 100
>>> z2[2, 1, 1]
100
>>>
You are using strides to say that I want to create a second array overlayed on top of the first array. You set its new shape, and you prefix 0 to the previous stride, indicating that the first dimension has no effect on the data you want.
Make sure you understand strides.
numpy.repeat creates a new array and not a view (you can check it by looking the __array_interface__ field). In fact, it is not possible to create a view on the original array in the general case since Numpy views does not support such pattern. A views is basically just an object containing a pointer to a raw memory buffer, some strides, a shape and a type. While it is possible to repeat one item N times with a 0 stride, it is not possible to repeat 2 items N times (without adding a new dimension to the output array). Thus, no there is no way to build a function like numpy.repeat having the same array output shape to repeat items of the last axis. If adding a new dimension is Ok, then you can build an array with a new dimension and a stride set to 0. Repeating the last dimension is possible though. The answer of #FrankYellin gives a good example. Note that reshaping/ravel the resulting array cause a mandatory copy. Supporting such advanced views would make the Numpy code more complex or/and less efficient for a feature that is only used rarely by users.
I have two matrices, A and B.
A=np.matrix([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
B=np.matrix([[1,1,1],[2,2,2],[3,3,3],[4,4,4]])
I want to substract some of B'rows (namely 0,2 and 3) from A. I tried to use
Index=np.array([0,2,3])
for i in Index:
A[i,:]=A[i,:]-B[i,:]
but it didn't work because matriz A should look like
matrix([[0, 1, 2],
[1, 2, 3],
[4, 5, 6],
[6, 7, 8]])
and I got
matrix([[ 1, 2, 3],
[ 2, 3, 4],
[ 7, 8, 9],
[10, 11, 12]])
What's the correct way to do this operation? I took me a long time to realize this problem (the real problem I'm trying to solve has more variables) and can't seem to figure it out.
If you do mean substract, then your should use
A[i,:]=A[i,:]-B[i,:]
instead of
A[i,:]=A[i,:]+B[i,:]
Numpy has element-wise subtraction, so something like:
import numpy as np
A=np.matrix([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
B=np.matrix([[1,1,1],[2,2,2],[3,3,3],[4,4,4]])
indices = [0,2,3]
for i in indices:
A[i,:]=np.subtract(A[i,:], B[i,:])
Will give you this matrix for A:
[[0, 1, 2],
[4, 5, 6],
[4, 5, 6],
[6, 7, 8]])
Is this what you are after? For better performance you could also just change the particular rows of A:
A[indices]=np.subtract(A[indices],B[indices])
Which will give the same answer.
Say I have 10 4*4 numpy arrays:
[[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]]
[[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5]]
etc...
What I want to do is calculate a least squares linear regression for each entry in the matrix.
So I want to take m0[0][0], m1[0][0], m2[0][0], etc... and calculate the linear regression. Then do the same for the [0][1] values.
Is there any way of doing this without having to first extract all [0][0] values into a new array and calling numpy.linalg.lstsq? Can I somehow pass my 10*4*4 array to numpy.linalg.lstsq so that it will calculate multiple regressions?
Give this a shot... I'm sure there is a way to make this more efficient though.
def my_lin_reg(arr0):
n = arr0.shape[0]
s = arr0.shape[1] * arr0.shape[2]
arr1 = arr0.swapaxes(0, 2).reshape(s, n)
x = np.vstack([range(n), np.ones(n)]).T
mc = []
for sub_arr in arr1:
mc.append(np.linalg.lstsq(x, sub_arr)[0])
return np.array(mc)
Need to take the values from one array, put them through a function and put them in another array. It is meant to be done using a pair of nested for loops. Please help. Complete beginner here.
EDIT: Ok to clarify, I have a 2-d array with various values in it. I want to apply a function to all of these values and have a 2-d array returned with the values after they have gone through the function. I am working in python. Thanks for the quick responses and any help you can give!
EDIT3: Example code:
import numpy as N
def makeGrid(dim):
''' Function to return a grid of distances from the centre of an array.
This version uses loops to fill the array and is thus slow.'''
tabx = N.arange(dim) - float(dim/2.0) + 0.5
taby = N.arange(dim) - float(dim/2.0) + 0.5
grid = N.zeros((dim,dim), dtype='float')
for y in range(dim):
for x in range(dim):
grid[y,x] = N.sqrt(tabx[x]**2 + taby[y]**2)
return grid
import math
def BigGrid(dim):
l= float(raw_input('Enter a value for lambda: '))
p= float(raw_input('Enter a value for phi: '))
a = makeGrid
b= N.zeros ((10,10),dtype=float) #Create an arry to take the returned values
for i in range(10):
for j in range (10):
b[i,j] = a[i][j]*2
if __name__ == "__main__":
''' Module test code '''
size = 10 #Dimension of the array
newGrid = BigGrid(size)
newGrid = N.round(newGrid, decimals=2)
print newGrid
def map_row(row):
return map(some_function,row)
map(map_row,my_2d_list)
Is probably how I would do it...
Based on your question, it appears you're using Numpy. If you're not too concerned about speed, you can simply call the function with a numpy array; the function will operate on the entire array for you.
There's no need to write the iteration explicitly, though if you can find a way to take advantage of numpy's special features, that will be faster than using a function designed to operate on one element at a time. Unless you're working with a very large dataset, though, this should be fine:
import numpy as np
>>> g = np.array( [ [1,2,3], [ 4,5,6] ] )
array([[1, 2, 3],
[4, 5, 6]])
>>> def myfunc( myarray ):
... return 2 * myarray
...
>>> myfunc(g)
array([[ 2, 4, 6],
[ 8, 10, 12]])
First, you have a bug in your code in the following line:
a = makeGrid
You are setting a to be a function, not an array. You should have the following:
a = makeGrid(dim)
That is why you had the TypeError when you tried the answer by #abought.
Now, to apply an operation element-wise in numpy there are many possibilities. If you want to perform the same operation for every element in the array, the simplest way is to use array operations:
b = a * 2
(Note that you don't need to declare b beforehand. And you also don't need any loops.) Numpy has also many C-optimised functions that perform the same operation on each element of an array. These are called ufuncs. You can combine ufuncs to get complex expressions evaluated element-wise. For example:
b = N.sin(a**2) + N.log(N.abs(a))
Your a array from makeGrid() can also be much more efficiently created using array operations and numpy's mgrid:
grid = N.mgrid[-dim//2 + 1:dim//2:0.5, -dim//2 + 1:dim//2:0.5]
grid = N.sqrt(grid[0]**2 + grid[1]**2)
If you want to perform different operations on each array element, things get more complicated and it may not be possible to avoid loops. For these cases, numpy has a way to decompose loops on a nD array using ndenumerate or ndidex. Your example with ndenumerate:
for index, x in N.ndenumerate(a):
b[index] = x * 2
This is faster than multiple loops, but the array operations should be used whenever possible.
From what I can get in terms of context from the question and what a 2d-array typically means it looks like you are trying to do the following:
>>>> array2d = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
>>> def add_two( v ):
... return v + 2
...
>>> [ [ add_two( v ) for v in row ] for row in array2d ]
[[2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6]]
The above uses a list comprehension which is the same as using the two nested for loops and in this case more readable and involves less direct interaction of the list methods as you're describing what the list is rather than building it.
Here is a one-line with double map
map(lambda x:map(func, x), l)
Example:
l=[[1,2,3],[4,3,1]]
map(lambda x:map(lambda x:x*10,x),l)
[[10, 20, 30], [40, 30, 10]]
Easy to do it with a nested loop:
def my_function(n): # n will become y from the next part
new_num = # do whatever you want with it
return new_num
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # just an example
new_list, final_list = [], [] # multiple assignment
for x in my_list:
print x
new_list = []
for y in x:
# y is now the first value of the first value of my_list--- 1.
my_num = my_function(y)
new_list.append(my_num)
final_list.append(new_list)
print final_list
That should do it.
Returns: [[2, 3, 4], [5, 6, 7], [8, 9, 10]].
for(int i; i < x; i++)
for(int j; j < y; j++)
array2[i][j] = func(array2[i][j])
Something like that?