17

Suppose I am getting a numpy matrix from some calculation. Here is my numpy matrix 'result1'::

    result1=
    [[   1.         0.         0.         0.00375   -0.01072   -0.      -1000.     ]
     [   2.         3.         4.         0.        -0.004    750.         0.     ]
     [   3.         3.         0.         0.         0.      -750.      1000.     ]]

Now I want to write this matrix in a text file named 'result.txt'. For this, I wrote the following code::

np.savetxt('result.txt', result1, fmt='%.2e')

But it is giving me all the elements of the matrix in one row.

    1.00e+00 0.00e+00 0.00e+00 3.75e-03 -1.07e-02 -1.14e-13 -1.00e+032.00e+00 3.00e+00 4.00e+00 0.00e+00 -4.00e-03 7.50e+02 0.00e+003.00e+00 3.00e+00 0.00e+00 0.00e+00 0.00e+00 -7.50e+02 1.00e+03

I want to write the matrix in the text file in the proper matrix format. How can I do this? I used keyword newline='\n' or newline='',but the result is same.

Thanks in advance...

=======

This edited part is for @Warren

try this one:

>>> import numpy as np
>>> mat=np.matrix([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
>>> mat
matrix([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])
>>> np.savetxt('text.txt',mat,fmt='%.2f')

in my text.txt file, I am getting:

1.00 2.00 3.004.00 5.00 6.007.00 8.00 9.00

Nafees
  • 231
  • 2
  • 4
  • 8
  • 2
    I can't reproduce this. If I give a 2-d array (or `np.matrix`) to `savetxt`, it creates a file with one line for each row of the array. Could you create a complete minimal example that we could run that gives the single line file? – Warren Weckesser Mar 01 '14 at 19:45
  • [This comment is a reply to a comment that was deleted.] Your example works as expected for me (with both numpy 1.7.1 and 1.8.0). How are you viewing the file 'text.txt'? I'm suspicious about the lack of a space between 3.00 and 4.00 and between 6.00 and 7.00 in the output that you showed. You sample output in the question also has spaces missing where the line separators would be. (Also, what operating system are you running this on? Might not matter, but it wouldn't hurt to know.) – Warren Weckesser Mar 01 '14 at 20:21
  • @WarrenWeckesser, please check the edited part. – Nafees Mar 01 '14 at 20:27
  • OK, thanks. My previous comment now applies to the change that you made to the question. – Warren Weckesser Mar 01 '14 at 20:30
  • @WarrenWeckesser, still i am getting single line. yes, there are no gap between 3.00 & 4.00 and 6.00 & 7.00. from 4.00 the 2nd row should start and from 7.00 the 3rd row. i am using python 3.3.0, numpy MKL 1.8.0, windows 7 – Nafees Mar 01 '14 at 20:32
  • This might be an issue with Windows + Python 3, but I don't have a system set up to try it myself. (In Windows 7 + Python 2.7 + numpy 1.7.1, it works as expected.) Can anyone else out there reproduce the problem? – Warren Weckesser Mar 01 '14 at 20:50
  • 1
    This looks related, although it only mentions python 2.7: https://github.com/numpy/numpy/pull/3976 (pull request) and https://github.com/numpy/numpy/issues/3975 (bug report). – Warren Weckesser Mar 01 '14 at 20:58

3 Answers3

8

like Francesco Nazzaro's answer, but a little different to make sure the file can be opened successfully, try:

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mat = np.matrix(a)
with open('outfile.txt','wb') as f:
    for line in mat:
        np.savetxt(f, line, fmt='%.2f')
DAYHU
  • 81
  • 1
  • 4
4

If you want to use only numpy:

import numpy as np

mat = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
with open('outfile.txt') as f:
    for line in mat:
        np.savetxt(f, line, fmt='%.2f')

and then

cat outfile.txt
1.00 2.00 3.00
4.00 5.00 6.00
7.00 8.00 9.00

Pandas has to_csv method:

import numpy as np
import pandas as pd

mat = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df = pd.DataFrame(data=mat.astype(float))
df.to_csv('outfile.csv', sep=' ', header=False, float_format='%.2f', index=False)

it has the same output:

cat outfile.csv
1.00 2.00 3.00
4.00 5.00 6.00
7.00 8.00 9.00
Community
  • 1
  • 1
Francesco Nazzaro
  • 2,688
  • 11
  • 20
2

To recreate the shape, you need to save the shape when you save the file.

Try:

import numpy as np
import re

result=np.array([[1.,0.,0.,0.00375,-0.01072,-0.,-1000.,],
                 [2.,3.,4.,0.,-0.004,750.,0.],
                 [3.,3.,0.,0.,0.,-750.,1000.]])

with open('/tmp/test', 'w') as fout:
    fout.write(u'#'+'\t'.join(str(e) for e in result.shape)+'\n')
    result.tofile(fout)

with open('/tmp/test', 'rb') as f:
    line=f.readline().decode('ascii')
    if line.startswith('#'):
        shape=tuple(map(int, re.findall(r'(\d+)', line)))
    else:
        raise IOError('Failed to find shape in file')    

    result2=np.fromfile(f)
    result3=result2.reshape(shape)

print(np.array_equal(result, result2))
# False
print(np.array_equal(result, result3))
# True

You can save the shape in some form in the file in oder to recreate the same shape. Make sure you do not forget the data at the beginning of the file however, since unlike np.loadtxt, lines starting with # are still considered data.

dawg
  • 98,345
  • 23
  • 131
  • 206