Aleph
Aleph

Reputation: 1373

Using numpy.ones as indices of an array

I would like to translate a matlab code into a python one. The matlab code is equivalent to the following toy example:

a = [1 2 3; 4 5 6; 7 8 9]
b = a(:, ones(1,3))

It returns

a =

 1     2     3
 4     5     6
 7     8     9

b =

 1     1     1
 4     4     4
 7     7     7

I tried to translate it like this:

from numpy import array
from numpy import ones

a = array([ [1,2,3], [4,5,6], [7,8,9] ])
b = a[:][ones((1,3))]

but it returns the following error message:

Traceback (most recent call last): File "example_slice.py", line 6, in b =a[:, ones((1,3))] IndexError: arrays used as indices must be of integer (or boolean) type

EDIT: maybe ones should be replaced by zeros in this particular case but it is not the problem here. The question deals with the problem of giving a list containing the same index many times to the array a in order to get the same array b as the one computed with Matlab.

Upvotes: 1

Views: 577

Answers (3)

hpaulj
hpaulj

Reputation: 231345

In [568]: a = np.array([ [1,2,3], [4,5,6], [7,8,9] ])                                
In [569]: a[:,0]                                                                     
Out[569]: array([1, 4, 7])
In [570]: a[:,[0,0,0]]                                                               
Out[570]: 
array([[1, 1, 1],
       [4, 4, 4],
       [7, 7, 7]])

In [571]: a[:, np.zeros(3, dtype=int)]  # int dtype to avoid your error                                       
Out[571]: 
array([[1, 1, 1],
       [4, 4, 4],
       [7, 7, 7]])

====

In [572]: np.zeros(3)                                                                
Out[572]: array([0., 0., 0.])
In [573]: np.zeros(3, int)                                                           
Out[573]: array([0, 0, 0])

Earlier numpy versions allowed float indices, but newer ones have tightened the requirement.

Upvotes: 1

Cris Luengo
Cris Luengo

Reputation: 60444

The MATLAB code can also be written (more idiomatically and more clearly) as:

b = repmat(a(:,1),1,3);

In NumPy you'd write:

b = np.tile(a[:,None,0],(1,3))

(Note the None needed to preserve the orientation of the vector extracted).

Upvotes: 2

Filip Młynarski
Filip Młynarski

Reputation: 3612

You could use list comprehension with np.full() to create arrays of certain values.

import numpy as np

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = np.array([np.full(len(i), i[0]) for i in a])

print(b)

Output:

[[1 1 1]
 [4 4 4]
 [7 7 7]]

Upvotes: 1

Related Questions