More "modern python" way of doing things.
[[ randint(0,4) for x in range(0,4)] for y in range(0,4)]
Its simply a pair of nested list comprehensions.
Answer from Shayne on Stack OverflowMore "modern python" way of doing things.
[[ randint(0,4) for x in range(0,4)] for y in range(0,4)]
Its simply a pair of nested list comprehensions.
The only time when you add 'rows' to the status array is before the outer for loop.
So - status[0] exists but status[1] does not.
you need to move status.append([]) to be inside the outer for loop and then it will create a new 'row' before you try to populate it.
Are you necessarily looking to use for-loops? I am asking because this problem can be solved in simpler and more efficient ways such as:
import numpy as np
a_values = np.random.rand(20,402) #Store random values in a_values with a shape of 20 rows and 402 columns
avg_columns = a_values.mean(axis=0) #Calculate the mean of each column
print(avg_columns)
Documentation for generating random values: numpy.random.rand
EDIT:
I assumed that xa is randomized in each iteration (make sure to replace it with the xa that you are generating). You can initialize an empty a_values array, and add the generated xa array to it in each iteration using np.vstack. For the first iteration, when a_value is empty, I made it equal to xa (if a_values.size else xa).
import numpy as np
a_values = np.array([])
for i in range(20):
xa = np.random.rand(1,402)
a_values = np.vstack([a_values, xa]) if a_values.size else xa
avg_columns = a_values.mean(axis=0) #Average of each column
Documentation for vstack: numpy.vstack
I don't think you can change the shape of A_values after it's defined. So you should start with:
A_values = numpy.zeros([20,402])
And if your for loop is iterating through the rows, your index should be [i, 1] (numpy array indexes are not like cartesian plane coords).
But you want to change entire rows of A_values, to do this you use just the first index:
A_values[row] = some_row
Remember that "some_row" needs to have the proper lenght, otherwise you get a ValueError.
Your final code will look like this:
A_values = numpy.zeros([20, 402])
for i in range(0,20):
A_values([i]) = xa
PS: You should describe the errors you are getting and be clearer if you want help with the "xa" values as well...
First you have to install numpy using
$ pip install numpy
Then the following should work
import numpy as np
n = 100
matrix = np.zeros((n,2)) # Pre-allocate matrix
for i in range(1,n):
matrix[i,:] = [3*i, i**2]
A faster alternative:
col1 = np.arange(3,3*n,3)
col2 = np.arange(1,n)
matrix = np.hstack((col1.reshape(n-1,1), col2.reshape(n-1,1)))
Even faster, as Divakar suggested
I = np.arange(n)
matrix = np.column_stack((3*I, I**2))
This is very pythonic form to produce a list, which you can easily swap e.g. for np.array, set, generator etc.
n = 10
[[i*3, i**2] for i, i in zip(range(0,n), range(0,n))]
If you want to add another column it's no problem. Simply
[[i*3, i**2, i**(0.5)] for i, i in zip(range(0,n), range(0,n))]
You should use numpy.zeros. If that isn't an option, you want the first version. In the second version, if you change one value, it will be changed elsewhere in the list -- e.g.:
>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
This is because (as you read the expression from the inside out), you create a list of 10 zeros. You then create a list of 10 references to that initial list of 10 zeros.
Note that this will also work and it avoids the nested list comprehension:
zeros = [ [0]*M for _ in range(N) ]
If numpy isn't on the table, this is the form I would use.
(Use xrange if you're still stuck in the python2.x dark ages :).)
for Python 3 (no more xrange), the preferred answer
zeros = [ [0] * N for _ in range(M)]
for M x N array of zeros
The four sums you want can be calculated efficiently like this:
import numpy as np
arr = np.array(data)
w = arr[0::2,0] # array([ 1, 3, 5, 13])
x = arr[0::2,1] # array([ 7, 9, 11, 14])
y = arr[1::2,0] # array([ 2, 4, 6, 15])
z = arr[1::2,1] # array([ 8, 10, 12, 16])
B = [[w.sum(), x.sum()], [y.sum(), z.sum()]]
arr[1::2,0] means "Starting from row 1, take every second row, then take column 0."
def slice_array(raw_data):
ret = [[0,0],
[0,0]]
for d in range(len(raw_data)):
if d % 2 == 0:
ret [0][0] += raw_data[d][0]
ret [0][1] += raw_data[d][1]
if d % 2 == 1:
ret [1][0] += raw_data[d][0]
ret [1][1] += raw_data[d][1]
return ret
This should work. Just give the array you want to slice as input.
Your mat:
In [352]: mat
Out[352]:
array([[ 1., -1., -1., -1.],
[ 1., -1., -1., -1.],
[ 1., 1., -1., -1.]])
broadcasting x against y:
In [353]: x[:,None]>y
Out[353]:
array([[ True, False, False, False],
[ True, False, False, False],
[ True, True, False, False]], dtype=bool)
turn that boolean mask into 1/-1 array with where:
In [354]: np.where(x[:,None]>y,1,-1)
Out[354]:
array([[ 1, -1, -1, -1],
[ 1, -1, -1, -1],
[ 1, 1, -1, -1]])
Or you could turn the boolean into a 0/1 array, and scale that to fit
(x[:,None]>y).astype(float)*2-1
A double loop over two 1d arrays or lists can often be cast as an outer operation like this.
It is possible to build 2 dimensional nested list comprehensions:
mat = np.array([[1 if x_ > y_ else -1 for y_ in y] for x_ in x])
However, this can become pretty unreadable, and is not much different from for loops as far performance scaling is concerned. Broadcasting and vectorization will usually work better with larger arrays:
mat = (x[:, None] > y[None, :]) * 2 - 1