bayesrule
bayesrule

Reputation: 125

Numpy, a 2 rows 1 column file, loadtxt() returns 1row 2 columns

2.765334406984874427e+00
3.309563282821381680e+00

The file looks like above: 2 rows, 1 col numpy.loadtxt() returns

[ 2.76533441  3.30956328]

Please don't tell me use array.transpose() in this case, I need a real solution. Thank you in advance!!

Upvotes: 2

Views: 2309

Answers (4)

J.Warren
J.Warren

Reputation: 778

I've written a wrapper for loadtxt to do this and is similar to answer from @petrichor, but I think matrix can't have a string data format (probably understandably) so and that method doesn't seem to work if you're loading strings (such as column headings).

def my_loadtxt(filename, skiprows=0, usecols=None, dtype=None):
    d = np.loadtxt(filename, skiprows=skiprows, usecols=usecols, dtype=dtype, unpack=True)
    if len(d.shape) == 0:
        d = d.reshape((1, 1))
    elif len(d.shape) == 1:
        d = d.reshape((d.shape[0], 1))
    return d

Upvotes: 0

Daniel
Daniel

Reputation: 19547

You can always use the reshape command. A single column text file loads as a 1D array which in numpy's case is a row vector.

>>> a
array([ 2.76533441,  3.30956328])

>>> a[:,None]
array([[ 2.76533441],
       [ 3.30956328]])

>>> b=np.arange(5)[:,None]
>>> b
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> np.savetxt('something.npz',b)
>>> np.loadtxt('something.npz')
array([ 0.,  1.,  2.,  3.,  4.])
>>> np.loadtxt('something.npz').reshape(-1,1) #Another way of doing it
array([[ 0.],
       [ 1.],
       [ 2.],
       [ 3.],
       [ 4.]])

You can check this using the number of dimensions.

data=np.loadtxt('data.npz')
if data.ndim==1: data=data[:,None]

Or

np.loadtxt('something.npz',ndmin=2) #Always gives at at least a 2D array.

Although its worth pointing out that if you always have a column of data numpy will always load it as a 1D array. This is more of a feature of numpy arrays rather then a bug I believe.

Upvotes: 7

Lisa
Lisa

Reputation: 3526

You might want to use the csv module:

import csv
import numpy as np

reader = csv.reader( open('file.txt') )
l = list(reader)
a = np.array(l)

a.shape
>>> (2,1)

This way, you will get the correct array dimensions irrespective of the number of rows / columns present in the file.

Upvotes: 1

petrichor
petrichor

Reputation: 6569

If you like, you can use matrix to read from string. Let test.txt involve the content. Here's a function for your needs:

import numpy as np

def my_loadtxt(filename):
    return np.array(np.matrix(open(filename).read().strip().replace('\n', ';')))

a = my_loadtxt('test.txt')
print a

It gives column vectors if the input is a column vector. For the row vectors, it gives row vectors.

Upvotes: 2

Related Questions