Adding a new column to a list of matrixs(arrays) - python

I have a problem with lists/arrays/matrix at Python.
I have a list of matrix (or arrays if it need to be) and i want to add to every single of of them a new column of ones (of the same number of lines). How can I do this??
I've a couple of things and didn't get any success.
Thanks for the help.
Here's an example:
>>> A=[mat([[1,2,3],[4,5,6],[7,8,9]]),mat([[1,0,0],[0,1,0],[0,0,1]])]
>>> A
[matrix([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]), matrix([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])]
Using the answer you guys told
>>> A = np.hstack((A, np.ones((A.shape[0],1),dtype=A.type)))
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
A = np.hstack((A, np.ones((A.shape[0],1),dtype=A.type)))
AttributeError: 'list' object has no attribute 'shape'`

Example for a 2D NumPy ndarray:
>>> m = np.arange(12).reshape(3,4)
>>> m = np.hstack((m, np.ones((m.shape[0], 1), dtype=m.dtype)))
>>> m
array([[ 0, 1, 2, 3, 1],
[ 4, 5, 6, 7, 1],
[ 8, 9, 10, 11, 1]])
Edit: It works the same for a matrix. For a list of matrices, you can use a for loop:
>>> matrices = [np.matrix(np.random.randn(3,4)) for i in range(10)]
>>> for i, m in enumerate(matrices):
... matrices[i] = np.hstack((m, np.ones((m.shape[0], 1), dtype=m.dtype)))

2d column arrays:
for matrix in matricies:
matrix.append([1,] * len(matrix[0]))
2d row arrays:
for matrix in matricies:
for row in matrix:
row.append(1)

Related

How to modify a list if a matrix contain a value?

I have a list with values [5, 5, 5, 5, 5] and I have a matrix too filled with with 1 and 0.
I want to have a new list that have to be like this:
if there's a 1 into the matrix then sum a '2' into the v's value if it's the first row and sum a '3' it's the second row.
example:
list:
v = [5,5,5,5,5]
matrix:
m = [[0, 1, 1, 0, 0], [0, 0, 1, 1, 0]]
final result:
v1 = [5,7,10,8,5]
Create a function that adds array lines, you can have the parameters be 1D numeric arrays. Loops through the arrays and returns a result array that is the addition of each element.
If your task requires it, add a check if the lines are of equal length and abort the function with an error if so.
Run this function on all of the matrix lines and then run it for the result of that and the input array.
Hope I managed to be comprehensive enough
You can use NumPy package for efficient code.
import numpy as np
v = [5,5,5,5,5]
matrix = [[0, 1, 1, 0, 0],
[0, 0, 1, 1, 0]]
weights = np.array([2,3])
w_matrix = np.multiply(matrix, weights[:, np.newaxis]).sum(axis=0)
v1 = v + w_matrix
classical python:
You can use a loop comprehension:
to_add = [sum((A*B) for A,B in zip(factors,x)) for x in zip(*m)]
[a+b for a,b in zip(v, to_add)]
output: [5, 7, 10, 8, 5]
numpy:
That said, this is a perfect use case for numpy that is more efficient and less verbose:
import numpy as np
v = [5,5,5,5,5]
m = [[0, 1, 1, 0, 0], [0, 0, 1, 1, 0]]
factors = [2,3]
V = np.array(v)
M = np.array(m)
F = np.array(factors)
V+(M*F[:,None]).sum(0)
output: array([ 5, 7, 10, 8, 5])

Create a numpy array of the form [1,x,x^2,...,x^n]

for a value x I want to create a numpy array of the form [1,x,x^2,x^3,...,x^n]. I found the function numpy.fromfunction, but i can't get it working. I tried the following:
np.fromfunction(lambda i: np.power(x,i), 10, dtype=int)
Can somebody explain why this doesn't work and how I can do this?
I know I can do this with a for loop, but I would prefer to use a numpy function.
If you have your variable x then you can just do
>>> x = 3
>>> np.power(x, np.arange(10))
array([ 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683], dtype=int32)
If you want x to be a matrix, just ensure that the dimensions are compatible, e.g.
>>> x = np.array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]])
>>> np.power(x, np.arange(3))
array([[ 1, 1, 1],
[ 1, 2, 4],
[ 1, 3, 9],
[ 1, 4, 16]], dtype=int32)
CoryKramer answer is likely the best way of achieving your desired result, but if you wanted to adapt your current approach to the problem, the code below would work:
np.fromfunction(lambda _, i: np.power(x,i), (1, 10), dtype=int)
For x = 3, this produces:
[ 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683]
This is because you were providing the value 10 for the array shape, instead of an iterable. The lambda function must then accept two values, so _ is used to collect the first value (which is always 0 for an array with the shape (1, 10)).

apply a function that takes an argument to an ndimage labeled array

I have an array that I've labeled using scipy.ndimage and I'd like to multiply each element by a factor specific to its corresponding label. I thought I could use ndimage.labeled_comprehension for this, however I can't seem to figure out how to pass an argument to the function. For example:
a = np.random.random(9).reshape(3,3)
lbls = np.repeat(np.arange(3),3).reshape(3,3)
ndx = np.arange(0,lbls.max()+1)
factors = np.random.randint(10,size=3)
>>> lbls
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]])
>>> ndx
array([0, 1, 2])
>>> factors
array([5, 4, 8])
def fn(a, x):
return a*x
>>> b = ndimage.labeled_comprehension(a, labels=lbls, index=ndx, func=fn, out_dtype=float, default=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/tgrant/anaconda/envs/python2/lib/python2.7/site-packages/scipy/ndimage/measurements.py", line 416, in labeled_comprehension
do_map([input], temp)
File "/Users/tgrant/anaconda/envs/python2/lib/python2.7/site-packages/scipy/ndimage/measurements.py", line 411, in do_map
output[i] = func(*[inp[l:h] for inp in inputs])
TypeError: fn() takes exactly 2 arguments (1 given)
As expected it gives an error since fn() needs factors fed into it somehow. Is labeled_comprehension able to do this?
Index into factors and then simply multiply with the image array -
a*factors[lbls]
Sample run -
In [483]: a # image/data array
Out[483]:
array([[ 0.10682998, 0.29631501, 0.08501469],
[ 0.46944505, 0.88346229, 0.75672908],
[ 0.11381292, 0.24096868, 0.86438641]])
In [484]: factors # scaling factors
Out[484]: array([8, 1, 1])
In [485]: lbls # labels
Out[485]:
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]])
In [486]: factors[lbls] # factors populated based on the labels
Out[486]:
array([[8, 8, 8],
[1, 1, 1],
[1, 1, 1]])
In [487]: a*factors[lbls] # finally scale the image array
Out[487]:
array([[ 0.85463981, 2.37052006, 0.68011752],
[ 0.46944505, 0.88346229, 0.75672908],
[ 0.11381292, 0.24096868, 0.86438641]])

How to add items into a numpy array

I need to accomplish the following task:
from:
a = array([[1,3,4],[1,2,3]...[1,2,1]])
(add one element to each row) to:
a = array([[1,3,4,x],[1,2,3,x]...[1,2,1,x]])
I have tried doing stuff like a[n] = array([1,3,4,x])
but numpy complained of shape mismatch. I tried iterating through a and appending element x to each item, but the changes are not reflected.
Any ideas on how I can accomplish this?
Appending data to an existing array is a natural thing to want to do for anyone with python experience. However, if you find yourself regularly appending to large arrays, you'll quickly discover that NumPy doesn't easily or efficiently do this the way a python list will. You'll find that every "append" action requires re-allocation of the array memory and short-term doubling of memory requirements. So, the more general solution to the problem is to try to allocate arrays to be as large as the final output of your algorithm. Then perform all your operations on sub-sets (slices) of that array. Array creation and destruction should ideally be minimized.
That said, It's often unavoidable and the functions that do this are:
for 2-D arrays:
np.hstack
np.vstack
np.column_stack
np.row_stack
for 3-D arrays (the above plus):
np.dstack
for N-D arrays:
np.concatenate
import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
b = np.array([10,20,30])
c = np.hstack((a, np.atleast_2d(b).T))
returns c:
array([[ 1, 3, 4, 10],
[ 1, 2, 3, 20],
[ 1, 2, 1, 30]])
One way to do it (may not be the best) is to create another array with the new elements and do column_stack. i.e.
>>>a = array([[1,3,4],[1,2,3]...[1,2,1]])
[[1 3 4]
[1 2 3]
[1 2 1]]
>>>b = array([1,2,3])
>>>column_stack((a,b))
array([[1, 3, 4, 1],
[1, 2, 3, 2],
[1, 2, 1, 3]])
Appending a single scalar could be done a bit easier as already shown (and also without converting to float) by expanding the scalar to a python-list-type:
import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
x = 10
b = np.hstack ((a, [[x]] * len (a) ))
returns b as:
array([[ 1, 3, 4, 10],
[ 1, 2, 3, 10],
[ 1, 2, 1, 10]])
Appending a row could be done by:
c = np.vstack ((a, [x] * len (a[0]) ))
returns c as:
array([[ 1, 3, 4],
[ 1, 2, 3],
[ 1, 2, 1],
[10, 10, 10]])
np.insert can also be used for the purpose
import numpy as np
a = np.array([[1, 3, 4],
[1, 2, 3],
[1, 2, 1]])
x = 5
index = 3 # the position for x to be inserted before
np.insert(a, index, x, axis=1)
array([[1, 3, 4, 5],
[1, 2, 3, 5],
[1, 2, 1, 5]])
index can also be a list/tuple
>>> index = [1, 1, 3] # equivalently (1, 1, 3)
>>> np.insert(a, index, x, axis=1)
array([[1, 5, 5, 3, 4, 5],
[1, 5, 5, 2, 3, 5],
[1, 5, 5, 2, 1, 5]])
or a slice
>>> index = slice(0, 3)
>>> np.insert(a, index, x, axis=1)
array([[5, 1, 5, 3, 5, 4],
[5, 1, 5, 2, 5, 3],
[5, 1, 5, 2, 5, 1]])
If x is just a single scalar value, you could try something like this to ensure the correct shape of the array that is being appended/concatenated to the rightmost column of a:
import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
x = 10
b = np.hstack((a,x*np.ones((a.shape[0],1))))
returns b as:
array([[ 1., 3., 4., 10.],
[ 1., 2., 3., 10.],
[ 1., 2., 1., 10.]])
target = []
for line in a.tolist():
new_line = line.append(X)
target.append(new_line)
return array(target)

Read flat list into multidimensional array/matrix in python

I have a list of numbers that represent the flattened output of a matrix or array produced by another program, I know the dimensions of the original array and want to read the numbers back into either a list of lists or a NumPy matrix. There could be more than 2 dimensions in the original array.
e.g.
data = [0, 2, 7, 6, 3, 1, 4, 5]
shape = (2,4)
print some_func(data, shape)
Would produce:
[[0,2,7,6],
[3,1,4,5]]
Cheers in advance
Use numpy.reshape:
>>> import numpy as np
>>> data = np.array( [0, 2, 7, 6, 3, 1, 4, 5] )
>>> shape = ( 2, 4 )
>>> data.reshape( shape )
array([[0, 2, 7, 6],
[3, 1, 4, 5]])
You can also assign directly to the shape attribute of data if you want to avoid copying it in memory:
>>> data.shape = shape
If you dont want to use numpy, there is a simple oneliner for the 2d case:
group = lambda flat, size: [flat[i:i+size] for i in range(0,len(flat), size)]
And can be generalized for multidimensions by adding recursion:
import operator
def shape(flat, dims):
subdims = dims[1:]
subsize = reduce(operator.mul, subdims, 1)
if dims[0]*subsize!=len(flat):
raise ValueError("Size does not match or invalid")
if not subdims:
return flat
return [shape(flat[i:i+subsize], subdims) for i in range(0,len(flat), subsize)]
For those one liners out there:
>>> data = [0, 2, 7, 6, 3, 1, 4, 5]
>>> col = 4 # just grab the number of columns here
>>> [data[i:i+col] for i in range(0, len(data), col)]
[[0, 2, 7, 6],[3, 1, 4, 5]]
>>> # for pretty print, use either np.array or np.asmatrix
>>> np.array([data[i:i+col] for i in range(0, len(data), col)])
array([[0, 2, 7, 6],
[3, 1, 4, 5]])
Without Numpy we can do as below as well..
l1 = [1,2,3,4,5,6,7,8,9]
def convintomatrix(x):
sqrt = int(len(x) ** 0.5)
matrix = []
while x != []:
matrix.append(x[:sqrt])
x = x[sqrt:]
return matrix
print (convintomatrix(l1))
[list(x) for x in zip(*[iter(data)]*shape[1])]
(found this post searching for how this works)

Categories

Resources