Shayan Monabbati
Shayan Monabbati

Reputation: 13

Trying to convert a MATLAB array to a Python array

I have this MATLAB code that I need to translate to python, however there is an issue in creating a new column in the firings array. In MATLAB, the code creates an n*2 matrix that is initially empty and I want to be able to do the same in python. Using NumPy, I created fired = np.where(v >= 30). However python creates a tuple rather than an array so it throws an error:

TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

This is the code I have in MATLAB that I would like converted into Python

firings=[];
firings=[firings; t+0*fired, fired];

Help is appreciated! Thanks!

Upvotes: 1

Views: 538

Answers (2)

rayryeng
rayryeng

Reputation: 104484

np.where generates a two-element tuple if the array is 1D in nature. For the 1D case, you would need to access the first element of the result of np.where only:

fired = np.where(v >= 30)[0]

You can then go ahead and concatenate the matrices. Also a suggestion provided by user @Divakar would be to use np.flatnonzero which would equivalently find the non-zero values in a NumPy array and flattened into a 1D array for less headaches:

fired = np.flatnonzero(v >= 30)

Take note that the logic to concatenate would not work if there were no matches found in fired. You will need to take this into account when you look at your concatenating logic. The convenient thing with MATLAB is that you're able to concatenate empty matrices and the result is no effect (obviously).

Also note that there is no conception of a row vector or column vector in NumPy. It is simply a 1D array. If you want to specifically force the array to be a column vector as you have it, you need to introduce a singleton axis in the second dimension for you to do this. Note that this only works provided that np.where gave you matched results. After, you can use np.vstack and np.hstack to vertically and horizontally concatenate arrays to help you do what you ask. What you have to do first is create a blank 2D array, then do what we just covered:

firings = np.array([[]]) # Create blank 2D array

# Some code here...
# ...
# ...

# fired = find(v >= 30); % From MATLAB
fired = np.where(v >= 30)[0]
# or you can use...
# fired = np.flatnonzero(v >= 30)

if np.size(fired) != 0:
    fired = fired[:, None] # Introduce singleton axis
    # Update firings with two column vectors
    # firings = [firings; t + 0 * fired, fired]; % From MATLAB
    firings = np.vstack([firings, np.hstack([t + 0*fired, fired])])

Here np.size finds the total number of elements in the NumPy array. If the result of np.where generated no results, the number of elements in fired should be 0. Therefore the if statement only executes if we have found at least one element in v subject to v >= 30.

Upvotes: 1

Nick
Nick

Reputation: 169

If you use numpy, you can define an ndarray:

import numpy as np
firings=np.ndarray(shape=(1,2)
firings[0][0:]=(1.,2.)
firings=np.append(firings,[[3.,4.]],axis=0)

Upvotes: 0

Related Questions