extract data from numpy array of shape () - python

I have a numpy array of shape () which for all intents and purposes is a scalar. If it contains a floating point number, I can simply float(arr) to get a float back. (That isn't ideal because of the implicit conversion though.)
How to extract the data if it's a more complicated (object) data type? E.g.:
import numpy
import sympy
x = sympy.Symbol("x")
val = numpy.array(2 * x)
print(val, val.shape, val.dtype)
2*x () object

val.item() or val[()] should work.

Related

How to check if a python object is a numpy ndarray

I have a function that takes an array as input and does some computation on it. The input array may or may not be a numpy ndarray (may be a list, pandas object, etc).
In the function, I convert the input array (regardless of its type) to a numpy ndarray. But this step may be computationally expensive for large arrays, especially if the function is called multiple times in a for loop.
Hence, I want to convert the input array to numpy ndarray ONLY if it is not already a numpy ndarray.
How can I do this?
import numpy as np
def myfunc(array):
# Check if array is not already numpy ndarray
# Not correct way, this is where I need help
if type(array) != 'numpy.ndarray':
array = np.array(array)
# The computation on array
# Do something with array
new_array = other_func(array)
return new_array
You're quite close, but you need to call the specific class, i.e numpy.ndarray (here you're just comparing with a string). Also for this you have the built-in isinstance, too see if a given object is an instance of another:
def myfunc(array):
# Check if array is not already numpy ndarray
if not isinstance(array, np.ndarray):
array = np.array(array)
# The computation on array
# Do something with array
new_array = other_func(array)
return new_array
You can use isinstance here.
import numpy as np
a=np.array([1,2,...])
isinstance(a,np.ndarray)
#True
def myfunc(array):
return array if isinstance(array,np.ndarray) else np.array(array)
You just return array if it's a np.ndarray already else you convert array to np.array.
It is simpler to use asarray:
def myfunc(arr):
arr = np.asarray(arr)
# The computation on array
# Do something with array
new_array = other_func(arr)
return new_array
If arr is already an array, asarray does not make a copy, so there's no penalty to passing it through asarray. Let numpy do the testing for you.
numpy functions often pass their inputs through asarray (or variant) just make sure the type is what they expect.
import numpy as np
def myfunc(array):
# Check if array is not already numpy ndarray
# Not correct way, this is where I need help
if bool(np.type(array)):
array = np.array(array)
else:
print('Big array computationally expensive')
array = np.array(array)
# The computation on array
# Do something with array
new_array = other_func(array)
return new_array

How to find roots for a numpy array

I am wondering how to find foots for an array. What I have now is:
import numpy as np
from scipy.optimize import brentq as find_root
t = np.linspace(0, 100)
def f(x):
return x ** 2 - t
a = find_root(f, -400, 400)
print(a)
It gives me a type array saying that:
TypeError: only size-1 arrays can be converted to Python scalars.
I know the reason is that find_root can only take a scalar in its argument. What I want is to make “a” a bumpy array that finds root for the function given each possible value of t. Does that mean I need to write a loop for find_root? Or do I need to write a loop before I define the function? What’s the easiest way to do it?
Thank you very much for helping.
Yes, in this case it might be easiest to just loop over the arguments.
import numpy as np
from scipy.optimize import brentq as find_root
def f(x, t):
return x ** 2 - t
a = [find_root(f, 0, 400,args=(i,)) for i in np.linspace(1,10,10)]
print(a)
Note that I introduced an argument t to your function f to which you can pass the value using the args parameter of find_root.

Multidimensional symbolic matrix in Python

I would like to create a 3D matrix of specific size by calculating a value for each combination of indexes. Each value in the matrix will be symbolic.
What I tried up to now:
import numpy as np
import sympy as sp
var1 = np.arange(1,10,2)
var2 = np.arange(1,10,2)
var3 = np.arange(20,50,5)
myMatrix = np.zeros(shape = (len(var1), len(var2), len(var3)))
t = sp.symbols('t')
for ii in range(len(var1)):
for jj in range(len(var2)):
for kk in range(len(var3)):
myMatrix[ii][jj][kk] = var1[ii] * var2[jj] * var3[kk] * t
This gives me the error:
TypeError: can't convert expression to float
which as far as I understand is due to combining numpy and sympy. Therefore, I tried:
myMatrix = sp.MatrixSymbol('temp', len(var1), len(var2), len(var3))
instead of:
myMatrix = np.zeros(shape = (len(var1), len(var2), len(var3)))
and got an error:
TypeError: new() takes exactly 4 arguments (5 given)
To sum up, my question is: how can I create a 3D matrix with any variables inside to be able to use it in the nested loop, which involves symbolic calculation?
(This is my first post in this community, so please let me know if I did anything wrong.)
The first error you get is, as you suggested, because you try to save a sympy type object into a numpy zeros array which is of type numbers. One option would be to use a numpy array of objects, which works as follows,
import numpy as np
import sympy as sp
var1 = np.arange(1,10,2)
var2 = np.arange(1,10,2)
var3 = np.arange(20,50,5)
myMatrix = np.empty((len(var1), len(var2), len(var3)), dtype=object)
t = sp.symbols('t')
for ii in range(len(var1)):
for jj in range(len(var2)):
for kk in range(len(var3)):
myMatrix[ii][jj][kk] = var1[ii] * var2[jj] * var3[kk] * t
Although for large sizes this isn't too efficient and not the way numpy should work. For sympy arrays this may be the only way to go however as it seems that, at least in my version of sympy (0.7.1.rc1), 3D arrays are not supported. For
myMatrix = sp.zeros((len(var1), len(var2), len(var3)))
I get the following error
ValueError: Matrix dimensions should be a two-element tuple of ints or a single int!

Tensor variable indexing

I'm trying to make some symbolic calculations using indexing of symbolic variable.
X = T.matrix('X')
y = T.matrix('y')
z = T.dot(T.dot(X,y[0]),y[1]).norm(L=2)
callable_function = theano.function([y,X], z)
callable_function(np.array([np.array([[3],[5]]),np.array([[4,1]])]),np.array([1,2]))
And I'm getting
AttributeError: ('Bad input argument to theano function with name "C:/Users/LIKAN/PycharmProjects/deepEEG/test.py:17" at index 0(0-based)', "'float' object has no attribute 'dtype'")
How to use symbolic variable indexing correctly?
You declare both y and X as matrices but your inputs to the compiled Theano function are an object array and a vector.
np.array([np.array([[3],[5]]),np.array([[4,1]])]) is an object array because it is constructed as an array of numpy arrays. Note that np.array([np.array([[3],[5]]),np.array([[4,1]])]).dtype == object.
To create a matrix, just use a multi-dimensional array in the numpy array construction. You don't even need to create numpy arrays, just pass vanilla Python lists. Since your second argument (for X) is a vector I've assumed the input value is correct and the symbolic variable declaration is incorrect. With these changes, the following code runs:
import numpy as np
import theano
import theano.tensor as T
X = T.vector('X')
y = T.matrix('y')
z = T.dot(T.dot(X,y[0]),y[1]).norm(L=2)
callable_function = theano.function([y,X], z)
print callable_function([[3,5],[4,1]], [1,2])

How to pass float argument in predict function of scikit linear regression?

I am using scikit linear regression - single variable to predict y from x. The argument is in float datatype. How can i transform the float into numpy array to predict the output ?
import matplotlib.pyplot as plt
import pandas
import numpy as np
from sklearn import linear_model
import sys
colnames = ['charge_time', 'running_time']
data = pandas.read_csv('trainingdata.txt', names=colnames)
data = data[data.running_time < 8]
x = np.array(list(data.charge_time))
y = np.array(list(data.running_time))
clf = linear_model.LinearRegression() # Creating a Linear Regression Modal
clf.fit(x[:,np.newaxis], y) # Fitting x and y array as training set
data = float(sys.stdin.readline()) # Input is Float e.g. 4.8
print clf.predict(data[:,np.newaxis]) # As per my understanding parameter should be in 1-D array.
First of all, a suggestion not directly related to your question:
You don't need to do x = np.array(list(data.charge_time)), you can directly call x = np.array(data.charge_time) or, even better, x = data.charge_time.values which directly returns the underlying ndarray.
It is also not clear to me why you're adding a dimension to the input arrays using np.newaxis.
Regarding your question, predict expects an array-like parameters: that can be a list, a numpy array, or other.
So you should be able to just do data = np.array([float(sys.stdin.readline())]). Putting the float value in a list ([]) is needed because without it numpy would create a 0-d array (i.e. a single value, which is not sliceable) instead of a 1-d array.

Categories