
Hi, when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector. I can only think of a solution using 'if' clauses but I suppose there is a more elegant way. Thanks, Christian

Christian <ckkart@hoc.net> writes:
Hi,
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector. I can only think of a solution using 'if' clauses but I suppose there is a more elegant way.
This will always return a column vector, but I'm not sure from you description if that's what you want (do you want [[1,2,3]] etc. to come out as a row-vector?) In [8]: ravel(array([1,2,3]))[:,newaxis] Out[8]: array([[1], [2], [3]]) 'as

On Wed, Feb 07, 2007 at 10:35:14AM +0000, Christian wrote:
Hi,
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector. I can only think of a solution using 'if' clauses but I suppose there is a more elegant way.
One way is to sub-class ndarray: import numpy as N class ColumnVectorArray(N.ndarray): def __new__(cls,data): data = N.asarray(data).view(cls) if len(data.shape) == 1: data.shape = (-1,1) return data x = ColumnVectorArray([[1,2],[3,4],[5,6]]) print 'x =' print x print y = ColumnVectorArray([1,2,3]) print 'y =' print y print print 'x+y =' print x+y which yields: x = [[1 2] [3 4] [5 6]] y = [[1] [2] [3]] x+y = [[2 3] [5 6] [8 9]] Cheers Stéfan

Christian schrieb:
Hi,
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector. I can only think of a solution using 'if' clauses but I suppose there is a more elegant way.
I'd be interested if you find a way without a single 'if'; I can't think of any, sorry. (which doesn't mean much, however... :-) Maybe your best bet is to make sure the lists are always nested at the source, if you have any control over that particular source. good luck, sven

Christian wrote:
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector.
I'm not sure I understand the specification of the problem. I would think that the definition of a column vector is that it's shape is: (-1,1) which makes it easy: def MakeColumn(input): a = asarray(input) a.shape = (-1,1) return a however, if you want: MakeColumn([[1,2],[3,4],[5,6]]) to return: array([[1, 2], [3, 4], [5, 6]]) that's not what I would call a column vector, and if that's what you want, then what would you want: MakeColumn([[1,2,3,4],[5,6,7,8]]) to return? -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

Christopher Barker schrieb:
Christian wrote:
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector.
I'm not sure I understand the specification of the problem. I would think that the definition of a column vector is that it's shape is:
(-1,1)
So I think what's needed is: b = array(yourlist) b.reshape(b.shape[0], -1) Now it seems I finally understood this business with the -1 in the shapes... (well it's trivial if you have the book :-) -sven

On 2/7/07, Sven Schreiber <svetosch@gmx.net> wrote:
Christopher Barker schrieb:
Christian wrote:
when creating an ndarray from a list, how can I force the result to be 2d *and* a column vector? So in case I pass a nested list, there will be no modification of the shape and when I pass a simple list, it will be converted to a 2d column vector.
I'm not sure I understand the specification of the problem. I would think that the definition of a column vector is that it's shape is:
(-1,1)
So I think what's needed is:
b = array(yourlist) b.reshape(b.shape[0], -1)
Now it seems I finally understood this business with the -1 in the shapes... (well it's trivial if you have the book :-)
I'd like to know what the -1 means. But first I'm trying to figure out why there are two reshapes? Do they behave identically? The doc strings make it look like they might not.
x = M.rand(3,3) x.reshape? Type: builtin_function_or_method Base Class: <type 'builtin_function_or_method'> String Form: <built-in method reshape of matrix object at 0xb4b41df4> Namespace: Interactive Docstring: a.reshape(d1, d2, ..., dn, order='c')
Return a new array from this one. The new array must have the same number of elements as self. Also always returns a view or raises a ValueError if that is impossible.;
M.reshape? Type: function Base Class: <type 'function'> String Form: <function reshape at 0xb776541c> Namespace: Interactive File: /usr/local/lib/python2.4/site-packages/numpy/core/fromnumeric.py Definition: M.reshape(a, newshape, order='C') Docstring: Return an array that uses the data of the given array, but with a new shape.
:Parameters: - `a` : array - `newshape` : shape tuple or int The new shape should be compatible with the original shape. If an integer, then the result will be a 1D array of that length. - `order` : 'C' or 'FORTRAN', optional (default='C') Whether the array data should be viewed as in C (row-major) order or FORTRAN (column-major) order. :Returns: - `reshaped_array` : array This will be a new view object if possible; otherwise, it will return a copy. :See also: numpy.ndarray.reshape() is the equivalent method.

Keith Goodman wrote:
I'd like to know what the -1 means.
It means "fill in with whatever is necessary to make the size correct given the other specified dimensions".
But first I'm trying to figure out why there are two reshapes?
reshape() used to be simply a function, not a method.
Do they behave identically? The doc strings make it look like they might not.
The docstrings are different only because I updated the one and not, yet, the other. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco

On 2/7/07, Christian <ckkart@hoc.net> wrote:
Sven Schreiber <svetosch <at> gmx.net> writes:
So I think what's needed is:
b = array(yourlist) b.reshape(b.shape[0], -1)
Row vectors are easy to get. In [1]: asmatrix([1,2,3,4]) Out[1]: matrix([[1, 2, 3, 4]]) And nested lists work, but you will be stuck with using matrices. Chuck

Christopher Barker <Chris.Barker <at> noaa.gov> writes:
I'm not sure I understand the specification of the problem. I would think that the definition of a column vector is that it's shape is:
(-1,1)
I was not aware of that possibility althoug I own the book I - shame on me. Thank you (and all others) for pointing that out. What I want is a 2d array regardless of whether the input is a simple or nested list. However if it is a simple list I want the result to be a column vector rather than a row vector, which happens by default. Like Sven I'm wondering if there is solution without using any 'if'. However using the subclassed array class which was proposed by Stefan is pretty elegant. Thanks to everybody, Christian
participants (8)
-
Alexander Schmolck
-
Charles R Harris
-
Christian
-
Christopher Barker
-
Keith Goodman
-
Robert Kern
-
Stefan van der Walt
-
Sven Schreiber