reading np array from a text file - python

i have this array in a text file:
[[0, 1, 3, 1, 3, 3, 1, 5, 2, 4, 4,],
[1, 0, 4, 1, 3, 1, 1, 3, 2, 2, 3,],
[4, 3, 1, 3, 4, 5, 2, 5, 4, 5, 0,]]
my code is written with python and i want to read it and use it as a np-array in my code, how can i do that.

The problem here is the formatting; you can clean that up with regex and then simply load the whole array with np.loadtxt(). Assuming your file is called 'array.txt':
import numpy as np
import re
with open('array.txt','r') as f:
txt = f.read()
nums = re.findall(r'\[([^][]+)\]', txt)
arr = np.loadtxt(nums)
print(arr)

You can use regular expressions to extract runs of numbers without square brackets, then split each run, and convert each substring into a number:
import re
runs = re.findall(r'\[([^][]+)\]', data)
np.array([[float(n) for n in run.split()]
for run in runs])
#array([[0., 1., 3., 1., 3., 3., 1., 5., 2., 4., 4.],
# [1., 0., 4., 1., 3., 1., 1., 3., 2., 2., 3.],
# [4., 3., 1., 3., 4., 5., 2., 5., 4., 5., 0.]])

Here a solution I've seen elsewhere (Read printed numpy array)
import re
import numpy as np
from ast import literal_eval
dat = """[[0. 1. 3. 1. 3. 3. 1. 5. 2. 4. 4.]
[1. 0. 4. 1. 3. 1. 1. 3. 2. 2. 3.]
[4. 3. 1. 3. 4. 5. 2. 5. 4. 5. 0.]]"""
a = re.sub('\s+', ',', dat)
a = np.array(literal_eval(a))
output:
array([[0., 1., 3., 1., 3., 3., 1., 5., 2., 4., 4.],
[1., 0., 4., 1., 3., 1., 1., 3., 2., 2., 3.],
[4., 3., 1., 3., 4., 5., 2., 5., 4., 5., 0.]])

Related

Multivariate (3D) Interpolation Using Vandermonde Matrix in Python

I can't seem to figure out how to implement the Vandermonde Matrix into Multivariate Interpolation. I am able to get the actual matrix, but I don't understand how to get the values (array) c00,c01,c02... . I know that c = V/z, but I feel like I am missing something (perhaps, not division?). I also know that I need to somehow set up a system of equations (the columns of V are each cij).
How do you do this in python?
Here is what I have so far:
import numpy as np
x = [1, 1, 1, 2, 2, 2, 3, 3, 3]
y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
z = [3.2, 4.4, 6.5, 2.5, 4.7, 5.8, 5.1, 3.6, 2.9]
numpy.polynomial.polynomial.polyvander2d(x, y, [2,2])
>>>array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 2., 4., 1., 2., 4., 1., 2., 4.],
[ 1., 3., 9., 1., 3., 9., 1., 3., 9.],
[ 1., 1., 1., 2., 2., 2., 4., 4., 4.],
[ 1., 2., 4., 2., 4., 8., 4., 8., 16.],
[ 1., 3., 9., 2., 6., 18., 4., 12., 36.],
[ 1., 1., 1., 3., 3., 3., 9., 9., 9.],
[ 1., 2., 4., 3., 6., 12., 9., 18., 36.],
[ 1., 3., 9., 3., 9., 27., 9., 27., 81.]])
np.dot(V, c.flat)and numpy.polynomial.polynomial.polyval2d(x, y, c) I think have to be incorporated into this somehow, but I don't know what to do. Please help!
I am supposed to output:
c = V \ z
c =
0.97500
-5.27500
5.95000
-3.92500
19.82500
-21.55000
3.40000
-14.70000
18.50000
Here is the site where I got this example (They used MatLab):
https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/05Interpolation/multi/
Hope this helps!
Given positions x and y:
x = [1, 1, 1, 2, 2, 2, 3, 3, 3]
y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
and function values z:
z = [3.2, 4.4, 6.5, 2.5, 4.7, 5.8, 5.1, 3.6, 2.9]
V will be the Vandermonde matrix:
V = numpy.polynomial.polynomial.polyvander2d(x, y, [2,2])
V = array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 2., 4., 1., 2., 4., 1., 2., 4.],
[ 1., 3., 9., 1., 3., 9., 1., 3., 9.],
[ 1., 1., 1., 2., 2., 2., 4., 4., 4.],
[ 1., 2., 4., 2., 4., 8., 4., 8., 16.],
[ 1., 3., 9., 2., 6., 18., 4., 12., 36.],
[ 1., 1., 1., 3., 3., 3., 9., 9., 9.],
[ 1., 2., 4., 3., 6., 12., 9., 18., 36.],
[ 1., 3., 9., 3., 9., 27., 9., 27., 81.]])
Each row:
a = x[i]
b = y[i]
V[i,:] = [ 1, b, b², a, a*b, a*b², a², a²b, a²b²]
A linear interpolation aims to solve:
$$z = V \cdot c$$
therefore we need to solve:
$$c = V^{-1} z$$
c = np.linalg.solve(V, z)
c now holds the coefficients in the same orders as the Vandermonde matrix does.
You can evaluate it manually:
def poly_eval(x, y, z):
return z[0] + z[1]*y + z[2]*np.power(y,2) + z[3]*x + z[4]*x*y + z[5]*x*np.power(y,2) + z[6]*np.power(x,2) + z[7]*np.power(x,2)*y + z[8]*np.power(x,2)*np.power(y,2)
or use
np.polynomial.polynomial.polyval2d([1,2], [3,4], c)
Out[22]: array([-65.5, -88.4])

numpy array indexing with negative index

First I have a scalar time series stored in a numpy array:
ts = np.arange(10)
which is
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Suppose I want to extract from ts a series of vectors (2,1,0), (3,2,1), (4,3,2), etc., I can think of the following code to do it:
for i in range(len(ts)-2):
print(ts[2+i:i-1:-1])
However, when i=0, the above code returns an empty array rather than [2,1,0] because the loop body will become
print(ts[2:-1:-1])
where the -1 in the middle creates trouble.
My question is: is there a way to make the indexing work for [2,1,0]?
You need use None:
ts = np.arange(10)
for i in range(len(ts)-2):
print(ts[2+i:None if i == 0 else i - 1:-1])
This should work too:
print(ts[i:i+3][::-1])
another way is to do the following
slices = np.arange(3)
result = np.array([])
while slices[2] < len(ts):
# print(ts[slices])
result = np.r_[result , ts[slices]]
slices += 1
result.reshape((-1 , 3))
Out[165]:
array([[ 0., 1., 2.],
[ 1., 2., 3.],
[ 2., 3., 4.],
[ 3., 4., 5.],
[ 4., 5., 6.],
[ 5., 6., 7.],
[ 6., 7., 8.],
[ 7., 8., 9.]])

Python - Find values whose coordinates are known in several times

I would like to get several values whose i have the coordinates.
My coordinates are given by "Coord" (shape : (3, 3, 2, 3) : X and Y during 3 times and with 2 because of 2 coordinates) and my values are given by "Values" (shape : (3, 3, 3) for 3 times)
In other words, i would like to concatenate values in time with "slices" for each positions...
I dont know how to undertake that...Here there is a little part of the arrays.
import numpy as np
Coord = np.array([[[[ 4., 6., 10.],
[ 1., 3., 7.]],
[[ 3., 5., 9.],
[ 1., 3., 7.]],
[[ 2., 4., 8.],
[ 1., 3., 7.]]],
[[[ 4., 6., 10.],
[ 2., 4., 8.]],
[[ 3., 5., 9.],
[ 2., 4., 8.]],
[[ 2., 4., 8.],
[ 2., 4., 8.]]],
[[[ 4., 6., 10.],
[ 3., 5., 9.]],
[[ 3., 5., 9.],
[ 3., 5., 9.]],
[[ 2., 4., 8.],
[ 3., 5., 9.]]]])
Values = np.array([[[-4.24045246, 0.97551048, -5.78904502],
[-3.24218504, 0.9771782 , -4.79103141],
[-2.24390519, 0.97882129, -3.79298771]],
[[-4.24087775, 1.97719843, -5.79065966],
[-3.24261128, 1.97886271, -4.7926441 ],
[-2.24433235, 1.98050192, -3.79459845]],
[[-4.24129055, 2.97886284, -5.79224713],
[-3.24302502, 2.98052345, -4.79422942],
[-2.24474697, 2.98215901, -3.79618161]]])
EDIT LATER
I try in case of a simplified problem (without time first). I have used a "for loop" but
somes errors seems subsist...do you think it s the best way to treat this problem? because my arrays are important... 400x300x100
Coord3 = np.array([[[ 2, 2.],
[ 0., 1.],
[ 0., 2.]],
[[ 1., 0.],
[ 2., 1.],
[ 1., 2.]],
[[ 2., 0.],
[ 1., 1.],
[ 0., 0.]]])
Coord3 = Coord3.astype(int)
Values2 = np.array([[0., 1., 2.],
[3., 4., 5.],
[6., 7., 8.]])
b = np.zeros((3,3))
for i in range(Values2.shape[0]):
for j in range(Values2.shape[1]):
b[Coord3[i,j,0], Coord3[i,j,1]] = Values2[i,j]
b
Your second example is relatively easy to do with fancy indexing:
b = np.zeros((3,3), values2.dtype)
b[coord3[..., 0], coord3[..., 1]] = values2
The origial problem is a bit harder to do, but I think this takes care of it:
coord = coord.astype(int)
x_size = coord[..., 0, :].max() + 1
y_size = coord[..., 1, :].max() + 1
# x_size, y_size = coord.max(axis=(0, 1, 3)) + 1
nt = coord.shape[3]
b = np.zeros((x_size, y_size, nt), values.dtype)
b[coord[..., 0, :], coord[..., 1, :], np.arange(nt)] = values

How do I concatenate an array into a 3D matrix?

In my Python application I have a 3D matrix (array) such this:
array([[[ 1., 2., 3.]], [[ 4., 5., 6.]], [[ 7., 8., 9.]]])
and I would like to add, in a particular "line", for example, in the middle, zero arrays. At the end I would like to end with the following matrix:
array([[[ 1., 2., 3.]],
[[ 4., 5., 6.]],
[[ 0., 0., 0.]],
[[ 0., 0., 0.]],
[[ 7., 8., 9.]]])
Anybody knows how to solve this issue? I tried to use "numpy.concatenate", but it allow me only to add more "lines".
Thanks in advance!
Possible duplicate of
Inserting a row at a specific location in a 2d array in numpy?
For example:
a = array([[[ 1., 2., 3.]], [[ 4., 5., 6.]], [[ 7., 8., 9.]]])
output = np.insert(a, 2, np.array([0,0,0]), 0)
output:
array([[[ 1., 2., 3.]],
[[ 4., 5., 6.]],
[[ 0., 0., 0.]],
[[ 7., 8., 9.]]])
Why this works on 3D array?
See doc here.
It says:
numpy.insert(arr, obj, values, axis=None)
...
Parameters :
values : array_like
Values to insert into arr.
If the type of values is different from that of arr,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
values is converted to the type of arr. values should be shaped so that
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arr[...,obj,...] = values is legal.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
So it's very wise function!!
Is this what you want?
result = np.r_[ a[:2], np.zeros(1,2,3), a[2][None] ]
I'd do it this way:
>>> a = np.array([[[ 1., 2., 3.]], [[ 4., 5., 6.]], [[ 7., 8., 9.]]])
>>> np.concatenate((a[:2], np.tile(np.zeros_like(a[0]), (2,1,1)), a[2:]))
array([[[ 1., 2., 3.]],
[[ 4., 5., 6.]],
[[ 0., 0., 0.]],
[[ 0., 0., 0.]],
[[ 7., 8., 9.]]])
The 2 in (2,1,1) given to tile() is how many zero "rows" to insert. The 2 in the slice indexes is of course where to insert.
If you're going to insert a large amount of zeros, it may be more efficient to just create a big array of zeros first and then copy in the parts you need from the original array.

Iterate with binary structure over numpy array to get cell sums

In the package scipy there is the function to define a binary structure (such as a taxicab (2,1) or a chessboard (2,2)).
import numpy
from scipy import ndimage
a = numpy.zeros((6,6), dtype=numpy.int)
a[1:5, 1:5] = 1;a[3,3] = 0 ; a[2,2] = 2
s = ndimage.generate_binary_structure(2,2) # Binary structure
#.... Calculate Sum of
result_array = numpy.zeros_like(a)
What i want is to iterate over all cells of this array with the given structure s. Then i want to append a function to the current cell value indexed in a empty array (example function sum), which uses the values of all cells in the binary structure.
For example:
array([[0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0],
[0, 1, 2, 1, 1, 0],
[0, 1, 1, 0, 1, 0],
[0, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0]])
# The array a. The value in cell 1,2 is currently one. Given the structure s and an example function such as sum the value in the resulting array (result_array) becomes 7 (or 6 if the current cell value is excluded).
Someone got an idea?
For the particular case of sums, you could use ndimage.convolve:
In [42]: import numpy as np
In [43]: a = np.zeros((6,6), dtype=np.int)
a[1:5, 1:5] = 1;
a[3,3] = 0;
a[2,2] = 2
In [48]: s = ndimage.generate_binary_structure(2,2) # Binary structure
In [49]: ndimage.convolve(a,s)
Out[49]:
array([[1, 2, 3, 3, 2, 1],
[2, 5, 7, 7, 4, 2],
[3, 7, 9, 9, 5, 3],
[3, 7, 9, 9, 5, 3],
[2, 4, 5, 5, 3, 2],
[1, 2, 3, 3, 2, 1]])
For the particular case of products, you could use the fact that log(a*b) = log(a)+log(b) to convert the problem back to one involving sums. For example, if we wanted to "product-convolve" b:
b = a[1:-1, 1:-1]
print(b)
# [[1 1 1 1]
# [1 2 1 1]
# [1 1 0 1]
# [1 1 1 1]]
we could compute:
print(np.exp(ndimage.convolve(np.log(b), s, mode = 'constant')))
# [[ 2. 2. 2. 1.]
# [ 2. 0. 0. 0.]
# [ 2. 0. 0. 0.]
# [ 1. 0. 0. 0.]]
The situation becomes more complicated if b includes negative values:
b[0,1] = -1
print(b)
# [[ 1 -1 1 1]
# [ 1 2 1 1]
# [ 1 1 0 1]
# [ 1 1 1 1]]
but not impossible:
logb = np.log(b.astype('complex'))
real, imag = logb.real, logb.imag
print(np.real_if_close(
np.exp(
sum(j * ndimage.convolve(x, s, mode = 'constant')
for x,j in zip((real, imag),(1,1j))))))
# [[-2. -2. -2. 1.]
# [-2. -0. -0. 0.]
# [ 2. 0. 0. 0.]
# [ 1. 0. 0. 0.]]
It's easier if you use a 2-deep wall of zeroes:
In [11]: a0
Out[11]:
array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 2., 1., 1., 0., 0.],
[ 0., 0., 1., 1., 0., 1., 0., 0.],
[ 0., 0., 1., 1., 1., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]])
In [12]: b0 = zeros_like(a0)
In [13]: for i in range(1,len(a0)-1):
....: for j in range(1,len(a0)-1):
....: b0[i,j] = sum(a0[i-1:i+2, j-1:j+2] * s)
This enables you to multiply the two sub-matrices together and sum, as desired. (You could also do something more elaborate here...)
In [14]: b0
Out[14]:
array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 2., 3., 3., 2., 1., 0.],
[ 0., 2., 5., 7., 7., 4., 2., 0.],
[ 0., 3., 7., 9., 9., 5., 3., 0.],
[ 0., 3., 7., 9., 9., 5., 3., 0.],
[ 0., 2., 4., 5., 5., 3., 2., 0.],
[ 0., 1., 2., 3., 3., 2., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]])
In [15]: b0[1:len(b0)-1, 1:len(b0)-1]
Out[15]:
array([[ 1., 2., 3., 3., 2., 1.],
[ 2., 5., 7., 7., 4., 2.],
[ 3., 7., 9., 9., 5., 3.],
[ 3., 7., 9., 9., 5., 3.],
[ 2., 4., 5., 5., 3., 2.],
[ 1., 2., 3., 3., 2., 1.]])

Categories