numpy m x n combination grid with m and n array - python

i was wondering if there is an easy way to do this:
a =
[[1,2],[3,4]]
b =
[[5,6],[7,8],[9,10]]
turning into this:
c =
[[[1,2], [1,2], [1,2]],
[[3,4], [3,4], [3,4]]]
d =
[[[5,6], [7,8], [9,10]],
[[5,6], [7,8], [9,10]]]
so i can do this:
c - d
i've already tried using np.meshgrid, but it was a really clunk:
indexes_b, indexes_a = np.meshgrid(
np.arange(a.shape[0]),
np.arange(b.shape[0])
)
c = a[indexes_a]
d = b[indexes_b]
c - d # works

Use broadcasting:
>>> a[:, None] - b
array([[[-4, -4],
[-6, -6],
[-8, -8]],
[[-2, -2],
[-4, -4],
[-6, -6]]])
>>> c - d
array([[[-4, -4],
[-6, -6],
[-8, -8]],
[[-2, -2],
[-4, -4],
[-6, -6]]])

Try this:
a = [[1,2],[3,4]]
b = [[5,6],[7,8],[9,10]]
c = [[li]*len(b[0]) for li in a]
d = [[li]*len(a) for li in b]
print(c)
print(d)

Related

Merging two lists in a certain format in Python

I have two lists A and B. I am trying to merge the two lists into one in a specific format as shown in the expected output. I also show the current output.
A=[0, 1]
B=[[1,2],[3,4]]
C=A+B
print(C)
The current output is
[0, 1, [1, 2], [3, 4]]
The expected output is
[[0, 1, 2], [1, 3, 4]]
lst=[]
for x, y in zip(A, B):
lst.append([x] + y)
#[[0, 1, 2], [1, 3, 4]]
Or as #Mechanic Pig suggested in comments using list comprehension:
[[a] + b for a, b in zip(A, B)]
You can also use np.insert:
a = np.array([0, 1])
b = np.array([[1, 2], [3, 4]])
np.insert(b, 0, a, axis=1)
A=[0, 1]
B=[[1,2],[3,4]]
c=[]
for i in range(len(A)):
c.append([A[i]])
for j in range(len(B[i])):
c[i].append(B[i][j])
print(c)
[[0, 1, 2], [1, 3, 4]]

Why are my answer's decimals incorrect in Python?

I am currently busy with a question that requires for one to solve Ax = b using Jacobi method where the function created must return x and the 2 norm of x.
The question states that when b is inputted as
b = [71; 42;-11;-37;-61; 52]
T = 2
N = 2
The answer that i am supposed to get is x = [2.73186728; 1.44791667; 0.62885802; 6.32696759; 6.390625; 3.33012821] and the norm of x 10.0953
However I get x = [ 3.07507642; 0.58675203; -0.64849988; 5.33343053; 6.66765397; 4.16161712] and the 2 norm of x 10.0221
I am trying to find where the error in my code is but finding it difficult...below is my code
import numpy as np
from numpy.linalg import norm
from numpy import array
from scipy.linalg import solve
def jacobi(A, b, x0, N):
n = A.shape[0]
x = x0.copy()
k = 0
x_prev= x0.copy()
for i in range(0, n):
subs = 0.0
for j in range(0, n):
if i != j:
subs += np.matrix(A[i,j])*np.matrix(x_prev[j])
x[i] = (b[i]-subs)/np.matrix(A[i,i])
k += 1
return(x)
A = array([[18, 1, 4, 3, -1, 2],
[2, 12, -1, 7, -2, 1],
[-1, 1, -9, 2, -5, 2],
[2, 4, 1, -12, 1, 3],
[1, 3, 1, 7, -16, 1],
[-2, 1, 7, -1, 2, 13]])
x0 = array([[0],[0],[0],[0],[0],[0]])
elements_of_b_and_N = list(map(float, input().split(' ')))
b_and_N = array(elements_of_b_and_N).reshape(A.shape[0]+1, )
b = b_and_N[:A.shape[0]]
N = b_and_N[A.shape[0]]
x = jacobi(A, b, x0, N)
print((solve(A, b)))
print(round(norm((solve(A,b)), 2), 4))
How did you compute the true value ?
The question states that when b is inputted as b = [71;
42;-11;-37;-61; 52]T and N = 2, the answer that i am supposed to get
is x = [2.73186728; 1.44791667; 0.62885802; 6.32696759; 6.390625;
3.33012821] and the norm of x 10.0953
When I execute :
x0 = array([[0], [0], [0], [0], [0], [0]], dtype=float)
A = array([[18, 1, 4, 3, -1, 2],
[2, 12, -1, 7, -2, 1],
[-1, 1, -9, 2, -5, 2],
[2, 4, 1, -12, 1, 3],
[1, 3, 1, 7, -16, 1],
[-2, 1, 7, -1, 2, 13]])
b = array([[71], [42], [-11], [-37], [-61], [52]], dtype=float)
print(solve(A, b))
I get :
[[ 3.07507642]
[ 0.58675203]
[-0.64849988]
[ 5.33343053]
[ 6.66765397]
[ 4.16161712]]
As you do with Jacobi.
Hope this helps :)

Pandas : transform a 2D dataframe to a 3D one

I have a Pandas dataframe like :
p1 p2 p3
t1 a b c
t2 d e f
t3 g h i
and I want either several df (or one xarray), one for each t(y axis)
like:
for t1: the value of pn minus pn for t1 :
p1 p2 p3
p1 a-a b-a c-a
p2 a-b b-b c-b
p3 a-c b-c c-c
idem for t2, t3 and so on...
I have made a loop like
for t in tlist :
for p in plist :
for q in plist :
res = p - q
but it's hugly and slow.
So if anyone know a pythonic way to do that, [s]he's very welcome !
This can be done in a quite simple manner leveraging numpy's broadcasting. Let's try with the following ndarray:
a = np.random.randint(1,10,(3,3))
print(a)
array([[9, 6, 4],
[2, 3, 6],
[8, 9, 2]])
a[:,None] - a[...,None]
array([[[ 0, -3, -5],
[ 3, 0, -2],
[ 5, 2, 0]],
[[ 0, 1, 4],
[-1, 0, 3],
[-4, -3, 0]],
[[ 0, 1, -6],
[-1, 0, -7],
[ 6, 7, 0]]])
This works by adding new axes to the arrays in such a way, that subtracting them yields the desired cartesian operation, since:
print(a[:,None])
array([[[9, 6, 4]],
[[2, 3, 6]],
[[8, 9, 2]]])
print(a[...,None])
array([[[9],
[6],
[4]],
[[2],
[3],
[6]],
[[8],
[9],
[2]]])
This can be done with broadcasting:
df = pd.DataFrame([[0,1,2],[3,6,8]])
# update as commented by piRSquared
a = df.to_numpy() # use a=df.values if on Pandas < 0.24
a = (a[:, None, :] - a[:,:,None]).reshape(-1, df.shape[1])
idx = pd.MultiIndex.from_product((df.index,df.columns), names=('t','p'))
pd.DataFrame(a, index=idx, columns=df.columns)
Output:
0 1 2
t p
0 0 0 1 2
1 -1 0 1
2 -2 -1 0
1 0 0 3 5
1 -3 0 2
2 -5 -2 0

Operation on numpy arrays contain rows with different size

I have two lists, looking like this:
a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]], b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
which I want to subtract from each other element by element for an Output like this:
a-b= [[-4,-4,-4,-4],[7,2,2,2],[-1,-1,-1,-1,-1]]
In order to do so I convert each of a and b to arrays and subtract them I use:
np.array(a)-np.array(b)
The Output just gives me the error:
Unsupported Operand type for-: 'list' and 'list'
What am I doing wrong? Shouldn't the np.array command ensure the conversion to the array?
Here is a Numpythonic way:
>>> y = map(len, a)
>>> a = np.hstack(np.array(a))
>>> b = np.hstack(np.array(b))
>>> np.split(a-b, np.cumsum(y))
[array([-4, -4, -4, -4]), array([-7, 2, 2, 2]), array([-1, -1, -1, -1, -1]), array([], dtype=float64)]
>>>
Since you cannot subtract the arrays with different shapes, you can flatten your arrays using np.hstack() then subtract your flattened arrays then reshape based on the previous shape.
You can try:
>>> a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
>>> b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
>>>
>>> c =[]
>>> for i in range(len(a)):
c.append([A - B for A, B in zip(a[i], b[i])])
>>> print c
[[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
Or
2nd method is using map:
from operator import sub
a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
c =[]
for i in range(len(a)):
c.append(map(sub, a[i], b[i]))
print c
[[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
The dimensions of your two arrays don't match, i.e. the first two sublists of a have 4 elements, but the third has 5 and ditto with b. If you convert the lists to numpy arrays, numpy silently gives you something like this:
In [346]: aa = np.array(a)
In [347]: bb = np.array(b)
In [348]: aa
Out[348]: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]], dtype=object)
In [349]: bb
Out[349]: array([[5, 6, 7, 8], [9, 1, 2, 3], [4, 5, 6, 7, 8]], dtype=object)
You need to make sure that all your sublists have the same number of elements, then your code will work:
In [350]: a = [[1,2,3,4], [2,3,4,5],[3,4,5,6]]; b = [[5,6,7,8], [9,1,2,3], [4,5,6,7]] # I removed the last element of third sublist in a and b
In [351]: np.array(a) - np.array(b)
Out[351]:
array([[-4, -4, -4, -4],
[-7, 2, 2, 2],
[-1, -1, -1, -1]])
Without NumPy:
result = []
for (m, n) in (zip(a, b)):
result.append([i - j for i, j in zip(m, n)])
See also this question and this one.
What about a custom function such as:
import numpy as np
a = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]]
b = [[5, 6, 7, 8], [9, 1, 2, 3], [4, 5, 6, 7, 8]]
def np_substract(l1, l2):
return np.array([np.array(l1[i]) - np.array(l2[i]) for i in range(len(l1))])
print np_substract(a, b)
You are getting the error, because your code is trying to subtract sublist from sublist, if you want to make it work, you can do the same in following manner:
import numpy as np
a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
#You can apply different condition here, like (if (len(a) == len(b)), then only run the following code
for each in range(len(a)):
list = np.array(a[each])-np.array(b[each])
#for converting the output array in to list
subList[each] = list.tolist()
print subList
A nested list comprehension will do the job:
In [102]: [[i2-j2 for i2,j2 in zip(i1,j1)] for i1,j1 in zip(a,b)]
Out[102]: [[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
The problem with np.array(a)-np.array(b) is that the sublists differ in length, so the resulting arrays are object type - arrays of lists
In [104]: np.array(a)
Out[104]: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]], dtype=object)
Subtraction is iterating over the outer array just fine, but hitting a problem when subtracting one sublist from another - hence the error message.
If I made the inputs arrays of arrays, the subtraction will work
In [106]: np.array([np.array(a1) for a1 in a])
Out[106]: array([array([1, 2, 3, 4]), array([2, 3, 4, 5]), array([3, 4, 5, 6, 7])], dtype=object)
In [107]: aa=np.array([np.array(a1) for a1 in a])
In [108]: bb=np.array([np.array(a1) for a1 in b])
In [109]: aa-bb
Out[109]:
array([array([-4, -4, -4, -4]),
array([-7, 2, 2, 2]),
array([-1, -1, -1, -1, -1])], dtype=object)
You can't count of array operations working on object dtype arrays. But in this case, subtraction is defined for the subarrays, so it can handle the nesting.
Another way to do the nesting is use np.subtract. This is a ufunc version of - and will apply np.asarray to its inputs as needed:
In [103]: [np.subtract(i1,j1) for i1,j1 in zip(a,b)]
Out[103]: [array([-4, -4, -4, -4]), array([-7, 2, 2, 2]), array([-1, -1, -1, -1, -1])]
Notice that these array calculations return arrays or a list of arrays. Turning the inner arrays back to lists requires iteration.
If you are starting with lists, converting to arrays often does not save time. Array calculations can be faster, but that doesn't compensate for the overhead in creating the arrays in the first place.
If I pad the inputs to equal length, then the simple array subtraction works, creating a 2d array.
In [116]: ao= [[1,2,3,4,0], [2,3,4,5,0],[3,4,5,6,7]]; bo= [[5,6,7,8,0], [9,1,2,3,0], [4,5,6,7,8]]
In [117]: np.array(ao)-np.array(bo)
Out[117]:
array([[-4, -4, -4, -4, 0],
[-7, 2, 2, 2, 0],
[-1, -1, -1, -1, -1]])

How to divide list item by list item from another list using Python?

I would like to divide list items inside two lists.
a = [[1, 0, 2], [0, 0, 0], [1], [1]]
b = [[5, 6, 4], [6, 6, 6], [3], [3]]
How can I divide a by b to obtain this output:
c = [[0.2, 0, 0.5], [0, 0, 0], [0.333], [0.333]]
Can anyone help me?
Zip the two lists and use a list comprehension:
from __future__ import division # in python2 only
result = [[x/y for x,y in zip(xs, ys)] for xs, ys in zip(a, b)]
Sample run:
In [1]: a = [[1, 0, 2], [0, 0, 0], [1], [1]]
...: b = [[5, 6, 4], [6, 6, 6], [3], [3]]
...:
In [2]: result = [[x/y for x,y in zip(xs, ys)] for xs, ys in zip(a, b)]
In [3]: result
Out[3]: [[0.2, 0.0, 0.5], [0.0, 0.0, 0.0], [0.3333333333333333], [0.3333333333333333]]
Using itertools.izip (Python2.7):
import itertools
[[float(aaa) / bbb for (aaa, bbb) in itertools.izip(aa, bb)] \
for (aa, bb) in itertools.izip(a, b)]
from __future__ import division # for Python2
[[x / y for x, y in zip(*item)] for item in zip(a, b)]

Categories

Resources