initiate 2d array with given ordered datasets - python

I don't know how to search key words in my case in search engine.
I want to make a 2d-array and each column means (x,y,z) from given 3 arrays.
x = [3,6,9,12]
y = [4,8,12,16]
z = [5,10,15,20]
to this:
[3,4,5],
[6,8,10],
[9,12,15],
[12,16,20]
my code is like below, is any better way to write this?
x = [3,6,9,12]
y = [4,8,12,16]
z = [5,10,15,20]
count=0
ans = []
for ind1 in range(4):
ans.append([x[count], y[count], z[count]])
count +=1

I will use numpy here.
import numpy as np
xyz = np.zeros((4, 3))
x = [3,6,9,12]
y = [4,8,12,16]
z = [5,10,15,20]
xyz[:, 0] = np.reshape(x, -1)
xyz[:, 1] = np.reshape(y, -1)
xyz[:, 2] = np.reshape(z, -1)

You can do this with zip
[ins] In [1]: x = [3,6,9,12]
...: y = [4,8,12,16]
...: z = [5,10,15,20]
[ins] In [2]: [list(x) for x in zip(x,y,z)]
Out[2]: [[3, 4, 5], [6, 8, 10], [9, 12, 15], [12, 16, 20]]

Related

Remove and append middle column from a 3D numpy array

Suppose I have a 3D numpy array A, say given below:
A = np.array( [[[1,2,3], [4,5,6]] , [[7,8,9] , [10,11,12], [13,14,15]] ] , ndmin = 3 )
The only thing given about A is that it is a 3D arrays which is an array of arbitrary number of 2D arrays, where each 2D array is an array of arbitrary number of 1D arrays, and each 1D array has exactly 3 elements.
I want to remove the middle element from each 1D array from this 3D array, basically get the new array A1, and the removed column as X given below:
A1 = np.array( [[[1,3], [4,6]] , [[7,9] , [10,12], [13,15]] ] , ndmin = 3 )
X = np.array( [ [[2],[5]], [[8],[11],[14]] ], ndmin = 3 )
I want to write a function that given A it outputs (A1, X) and another function which given (A1, X) outputs A. I believe it should be possible to write the first function via array slicing, but I am not able to do so. Also how do I write the second function.
For you ragged array, it is better to store in a list of np.arrays with shape n by 3:
A = [np.array([[1,2,3],
[4,5,6]]) ,
np.array([[7,8,9],
[10,11,12],
[13,14,15]])]
Now you could:
def remove_middle(arr):
x = [a[:, 1] for a in arr]
arr_new = [np.delete(a, 1, axis = 1) for a in arr]
return arr_new, x
def insert_middle(arr, x):
return [np.concatenate([a[:, :1], xx.reshape(-1, 1), a[:, 1:]], axis = 1) for a, xx in zip(arr, x)]
remove_middle(A)
([array([[1, 3],
[4, 6]]),
array([[ 7, 9],
[10, 12],
[13, 15]])],
[array([2, 5]), array([ 8, 11, 14])])
insert_middle(*remove_middle(A))
# gets back the original A
[array([[1, 2, 3],
[4, 5, 6]]),
array([[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]])]
Without the ndmin=3 argument I can solve your answer using two nested list comprehensions in which the first indexes the middle argument and the second one deletes the middle argument of the inner arrays.
import numpy
A = np.array([[[1,2,3], [4,5,6]] , [[7,8,9] , [10,11,12], [13,14,15]]])
middle = [[array1d[1] for array1d in array2d] for array2d in A]
without_middle = [[np.delete(array1d, 1) for array1d in array2d] for array2d in A]
With your strange data, this absurd-looking quintuple-nested list-comprehension is the best I could come up with :P
A1 = [[[[[e for i, e in enumerate(d) if i != 1] for d in c] for c in b] for b in a] for a in A]
X = [[[[[e for i, e in enumerate(d) if i == 1] for d in c] for c in b] for b in a] for a in A]
Output:
>>> A1
[[[[[1, 3], [4, 6]], [[7, 9], [10, 12], [13, 15]]]]]
>>> X
[[[[[2], [5]], [[8], [11], [14]]]]]
Here is a solution. Note that lists are returned as raw python list which you can use as you want.
I changed your definition of A to a more suitable object.
import numpy as np
def f(A):
A1 = A.tolist()
X = []
for i in range(len(A1)):
temp = []
for j in range(len(A1[i])):
temp.append([A1[i][j].pop(1)])
X.append(temp)
return (A1, X)
def g(A1, X):
A = A1
for i in range(len(A1)):
for j in range(len(A1[i])):
A[i][j].insert(1, X[i][j][0])
return A
def main():
#A = np.array( [ [ [1,2,3], [4,5,6] ] , [ [7,8,9] , [10,11,12], [13,14,15] ] ] , ndmin = 3 )
A = np.asarray([ [ [1,2,3], [4,5,6] ] , [ [7,8,9] , [10,11,12], [13,14,15] ] ])
B, X = f(A)
print(g(B,X))
if __name__ == '__main__':
main()
Finally please note that this is one solution among many possible alternatives.

Using Pandas/NumPy to increase resolution

I need to change the number of point in array, so the new point y value will be the same value as the original point on the left side.
import numpy as np
def regularizeSeries1(x, y, M = 100):
s0 = (x - x[0])
s1 = np.linspace(0, max(s0), M + 1)
z = np.empty(M)
for i in range(M):
z[i] = y[(s0 <= s1[i])][-1]
return(z)
x = np.array([0, 1, 2, 5, 7,8 ,10])
y = np.array([0, 1, 3,4, 6, 7.5, 9])
M = 20
Z = regularizeSeries1(x, y, M)
How can I do it without loop using Pandas or numpy?
[][1
merge and fill the nan using pd.ffill
import pandas as pd
import numpy as np
M = 20
x = np.array([0, 1, 2, 5, 7,8 ,10])
y = np.array([0, 1, 3,4, 6, 7.5, 9])
s1 = np.linspace(0, max(s0), M)
df1 = pd.DataFrame({'x': x, 'y': y})
df2 = pd.DataFrame({'x': s1})
df3 = df1.merge(df2, on='x', how='outer').sort_values(by='x').ffill().reset_index(drop=True)
df3 = df3[df3['x'].isin(df2['x'])]
newX, newY = df3['x'], df3['y']

More "pythonic" way to show a 4d matrix in 2d

I would like to plot a 4d matrix as a 2d matrix with indices:
[i][j][k][l] --> [i * nj + j][ k * nl + l]
I have a working version here.
This is working as I want, but it's not very elegant. I looked into "reshape" but this is not exactly what I'm looking for, or perhaps I am using it incorrectly.
Given a 4d array "r" with shape (100000,4), the relevant snippet I want to replace is:
def transform(i,j,k,l, s1, s2):
return [i * s1 + j, k * s2 + l]
nx = 5
ny = 11
iedges=np.linspace(0,100, nx)
jedges=np.linspace(0, 20, ny)
bins = ( iedges,jedges,iedges,jedges )
H, edges = np.histogramdd(r, bins=bins )
H2 = np.zeros(( (nx-1)*(ny-1),(nx-1)*(ny-1)))
for i in range(nx-1):
for j in range(ny-1):
for k in range(nx-1):
for l in range(ny-1):
x,y = transform(i,j,k,l,ny-1,ny-1)
H2[x][y] = H[i][j][k][l]
In this case the values of H2 will correspond to the values of H, but the entry i,j,k,l will display as i*ny + j, k * ny + l.
Example plot:
Are you sure reshape doesn't work?
I ran your code on a small random r. The nonzero terms of H are:
In [13]: np.argwhere(H)
Out[13]:
array([[0, 9, 3, 1],
[1, 1, 1, 2],
[1, 2, 1, 3],
[2, 2, 2, 3],
[3, 1, 1, 8]])
and for the transformed H2:
In [14]: np.argwhere(H2)
Out[14]:
array([[ 9, 31],
[11, 12],
[12, 13],
[22, 23],
[31, 18]])
And one of the H indices transforms to H2 indices with:
In [16]: transform(0,9,3,1,4,10)
Out[16]: [9, 31]
If I simply reshape H, I get the same array as H2:
In [17]: H3=H.reshape(40,40)
In [18]: np.argwhere(H3)
Out[18]:
array([[ 9, 31],
[11, 12],
[12, 13],
[22, 23],
[31, 18]])
In [19]: np.allclose(H2,H3)
Out[19]: True
So without delving into the details of your code, it looks to me like a simple reshape.
Looks like you can calculate i,j,k,l from x,y? This should be something like:
from functools import partial
def get_ijkl(x, y, s1, s2):
# "Reverse" of `transform`
i, j = divmod(x, s1)
k, l = divmod(y, s2)
return (i, j, k, l)
def get_2d_val(x, y, s1, s2, four_dim_array):
return four_dim_array[get_ijkl(x, y, s1, s2)]
smaller_shape = ((nx-1)*(ny-1), (nx-1)*(ny-1))
Knowing this there are several approaches possible:
numpy.fromfunction:
H3 = np.fromfunction(
partial(get_2d_val, s1=ny-1, s2=ny-1, four_dim_array=H),
shape=smaller_shape,
dtype=int,
)
assert np.all(H2 == H3)
by indexing:
indices_to_take = np.array([
[list(get_ijkl(x, y, ny-1, ny-1)) for x in range(smaller_shape[0])] for y in range(smaller_shape[1])
]).transpose()
H4 = H[tuple(indices_to_take)]
assert np.all(H2 == H4)
as answered by #hpaulj you can simply reshape array and it will be faster. But If you have some different transform and can calculate appropriate "reverse" function then using fromfunction or custom indexing will get useful

How to shuffle a matrix and an array accordingly

Suppose I have an mXd matrix called X, and an mX1 array called Y (using numpy). The rows of X correspond to the rows of Y.
Now suppose I need to shuffle the data (the rows) in X. I used:
random.shuffle(X)
Is there a way for me to keep track of the way X has been shuffled, so I could shuffle Y accordingly?
Thank you :)
You can use numpy.random.permutation to create a permuted list of indices, and then shuffle both X and Yusing those indices:
>>> import numpy
>>> m = 10
>>> X = numpy.random.rand(m, m)
>>> Y = numpy.random.rand(m)
>>> indices = numpy.random.permutation(m)
>>> indices
array([4, 7, 6, 9, 0, 3, 1, 2, 8, 5])
>>> Y
array([ 0.53867012, 0.6700051 , 0.06199551, 0.51248468, 0.4990566 ,
0.81435935, 0.16030748, 0.96252029, 0.44897724, 0.98062564])
>>> Y = Y[indices]
>>> Y
array([ 0.4990566 , 0.96252029, 0.16030748, 0.98062564, 0.53867012,
0.51248468, 0.6700051 , 0.06199551, 0.44897724, 0.81435935])
>>> X = X[indices, :]

matrix using python

I'm new to python and I'm writing a program fro matrix but there is a problem I don't know to get the right output and I need help with it.
this is the question:Given a nXn matrix A and a kXn matrix B find AB .
and here is what I have so far. Thank you in advance
def matrixmult (A, B):
rows_A = len(A)
cols_A = len(A[0])
rows_B = len(B)
cols_B = len(B[0])
if cols_A != rows_B:
print "Cannot multiply the two matrices. Incorrect dimensions."
return
# Create the result matrix
# Dimensions would be rows_A x cols_B
C = [[0 for row in range(cols_B)] for col in range(rows_A)]
print C
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
C[i][j] += A[i][k]*B[k][j]
return C
Your function:
def matrixmult (A, B):
rows_A = len(A)
cols_A = len(A[0])
rows_B = len(B)
cols_B = len(B[0])
if cols_A != rows_B:
print "Cannot multiply the two matrices. Incorrect dimensions."
return
# Create the result matrix
# Dimensions would be rows_A x cols_B
C = [[0 for row in range(cols_B)] for col in range(rows_A)]
print C
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
C[i][j] += A[i][k]*B[k][j]
return C
Which appears to be the same as this function.
If I run this:
matrix=[[1,2,3],
[4,5,6],
[7,8,9]]
print matrixmult(matrix, matrix) # that is your function...
It returns:
[[30, 36, 42], [66, 81, 96], [102, 126, 150]]
This is the same as Numpy:
import numpy as np
a=np.array(matrix)
b=np.array(matrix)
print np.dot(a,b)
# [[ 30 36 42]
[ 66 81 96]
[102 126 150]]
And the same as the matrix multiply more tersely stated:
def mult(mtx_a,mtx_b):
tpos_b = zip( *mtx_b)
rtn = [[ sum( ea*eb for ea,eb in zip(a,b)) for b in tpos_b] for a in mtx_a]
return rtn
So -- it is probably your input data that is the issue.
Use numPy library to solve your problem.
import numpy as np
x = np.array( ((2,3), (3, 5)) )
y = np.array( ((1,2), (5, -1)) )
print x * y
array([[ 2, 6],
[15, -5]])
More examples:
http://www.python-course.eu/matrix_arithmetic.php
Download numPy:
http://scipy.org/Download
One liner:
def matrixmult(m1, m2):
return [
[sum(x * y for x, y in zip(m1_r, m2_c)) for m2_c in zip(*m2)] for m1_r in m1
]
Explanation:
zip(*m2) - gets a column from the second matrix
zip(m1_r, m2_c) - creates tuple from m1 row and m2 column
sum(...) - sums multiplication row * col
Test:
m1 = [[1, 2, 3], [4, 5, 6]]
m2 = [[7, 8], [9, 10], [11, 12]]
result = matrixmult(m1, m2)
assert result == [[58, 64], [139, 154]]

Categories

Resources