CasualPythoner
CasualPythoner

Reputation: 69

Save a numpy array consisting of numpy arrays different shapes to a .txt file

I am a beginner in Python. Here's what I am trying to do :

import numpy as np 
r10 = np.array([[i for i in range(0,10)],[i*10 for i in range(0,10)]]).T
r6 = np.array([[i for i in range(0,6)],[i*10 for i in range(0,6)]]).T
r_comb = np.array([[r10],[r6]]).T
np.savetxt('out.txt',r_comb)

Using np.savetxt gives me the following error since it only supports 1-D array :

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python38-32\lib\site-packages\numpy\lib\npyio.py in savetxt(fname, X, fmt, delimiter, newline, header, footer, comments, encoding)
   1433                 try:
-> 1434                     v = format % tuple(row) + newline
   1435                 except TypeError:

TypeError: only size-1 arrays can be converted to Python scalars

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-88-c3147f076055> in <module>
----> 1 np.savetxt('out.txt',r_comb)

<__array_function__ internals> in savetxt(*args, **kwargs)

~\AppData\Local\Programs\Python\Python38-32\lib\site-packages\numpy\lib\npyio.py in savetxt(fname, X, fmt, delimiter, newline, header, footer, comments, encoding)
   1434                     v = format % tuple(row) + newline
   1435                 except TypeError:
-> 1436                     raise TypeError("Mismatch between array dtype ('%s') and "
   1437                                     "format specifier ('%s')"
   1438                                     % (str(X.dtype), format))

TypeError: Mismatch between array dtype ('object') and format specifier ('%.18e %.18e')

Is there any other way of saving the contents of the variable r_comb to a .txt file so that I can use it for other plotting programs? Basically,I want the text file to look like this :

0 0.0 0 0.0
1 0.1 1 0.1
2 0.2 2 0.2
3 0.3 3 0.3
4 0.4 4 0.4
5 0.5 5 0.5
6 0.6
7 0.7
8 0.8
9 0.9

Image showing how the contents of the text file should look

enter image description here

Upvotes: 2

Views: 1330

Answers (2)

hpaulj
hpaulj

Reputation: 231375

Your r_comb is an array of arrays:

In [313]: r_comb                                                                        
Out[313]: 
array([[array([[ 0,  0],
       [ 1, 10],
       [ 2, 20],
       [ 3, 30],
       [ 4, 40],
       [ 5, 50],
       [ 6, 60],
       [ 7, 70],
       [ 8, 80],
       [ 9, 90]]),
        array([[ 0,  0],
       [ 1, 10],
       [ 2, 20],
       [ 3, 30],
       [ 4, 40],
       [ 5, 50]])]], dtype=object)
In [314]: _.shape                                                                       
Out[314]: (1, 2)

savetxt is designed to save a nice numeric 2d array. The default fmt is '%.18e' (read the docs). Obviously that can't format an array.

I could 'flatten' that into one 2d array with:

In [320]: np.vstack(r_comb[0,:])                                                        
Out[320]: 
array([[ 0,  0],
       [ 1, 10],
       [ 2, 20],
       [ 3, 30],
       [ 4, 40],
       ....
       [ 4, 40],
       [ 5, 50]])

and write that to a file with (note the change in fmt):

In [321]: np.savetxt('test.csv', np.vstack(r_comb[0,:]), fmt='%5d')                     
In [322]: cat test.csv                                                                  
    0     0
    1    10
    2    20
    3    30
    4    40
    ...
    4    40
    5    50

The layout you propose does not fit the example array. And even if you managed to write it, how do you propose to read it? The numpy readers expect a consistent number of columns in each row.

0 0.0 0 0.0
1 0.1 1 0.1
2 0.2 2 0.2
3 0.3 3 0.3
4 0.4 4 0.4
5 0.5 5 0.5
6 0.6
7 0.7
8 0.8
9 0.9

You could call savetxt twice on the same file (with append mode if needed), and save the two arrays one after the other. And with some work you could also load it with two calls to genfromtxt. But that's a lot of work for a Python beginner!

Upvotes: 1

mujjiga
mujjiga

Reputation: 16856

Hacky but works

import numpy as np 
r10 = np.array([[i for i in range(0,10)],[i*10 for i in range(0,10)]]).T
r6 = np.array([[i for i in range(0,6)],[i*10 for i in range(0,6)]]).T

# np array with nans
data = np.empty((np.max([r10.shape[0], r6.shape[0]]),4))
data[:] = np.NaN
for i in range(2):
  data[0:len(r10[:,i]), i] = r10[:, i]

for i in range(2):
  data[0:len(r6[:,i]), i+2] = r6[:, i]

# replace nans and save
data = data.astype(str)
data[data=='nan'] = ''
np.savetxt("out.txt", data, delimiter=" ", fmt="%s")

Contents of out.txt

0.0 0.0 0.0 0.0
1.0 10.0 1.0 10.0
2.0 20.0 2.0 20.0
3.0 30.0 3.0 30.0
4.0 40.0 4.0 40.0
5.0 50.0 5.0 50.0
6.0 60.0  
7.0 70.0  
8.0 80.0  
9.0 90.0

Upvotes: 1

Related Questions