简体   繁体   中英

Python/Numpy - writing multiple 1D arrays to a file in neat columns

How do you create a text file in python/numpy that displays multiple 1D arrays, side-by-side, in neat aligned columns (ie, delimited by whitespace). I would also like to include the names of the arrays at the top of the column.

Here is an example that I have been working with. (Note, the strings in the a['site'] array are of different character lengths resulting in unaligned columns)

import numpy as np
dt = np.dtype([('site', '|S11'), ('year', 'i'), ('dat1', 'd'), ('dat2', 'd')])
a = np.zeros(2, dt)
a['site'] = ['Paris', 'London']
a['year'] = [1979, 1980]
a['dat1'] = [272.4322, 270.36]
a['dat2'] = [2.21, 3.55]
np.savetxt('test.txt', a, '%s')

Ideally I would want something that can produce a file like this: http://www.antarctica.ac.uk/data/absl/ABSL-index-Monthly-ERA-Interim_Hosking2013.txt

I have now found an answer to this questions, see the following... https://stackoverflow.com/a/19676112/1310153

Try this:

import numpy as np

dt = np.dtype([('site', '|S11'), ('year', 'i'), ('dat1', 'd'), ('dat2', 'd')])
a = np.zeros(2, dt)
a['site'] = ['Paris', 'London']
a['year'] = [1979, 1980]
a['dat1'] = [272.4322, 270.36]
a['dat2'] = [2.21, 3.55]

np.savetxt('test.txt', a, '%10s')

In '%10s' , 10 is the field width.

You can do something like:

header = '#\n# Amundsen-Bellingshausen Seas Low (ABSL) Monthly Index\n# (based on ERA-Interim Reanalysis data)\n#\n# Dr J. Scott Hosking\n# British Antarctic Survey\n#\n# For more inforation see:\n# Hosking et al., 2013: The influence of the Amundsen-Bellingshausen Seas Low on the\n# climate of WestAntarctica and its representation in coupled climate model simulations, J.Climate\n#\n# Updated dataset can be found at: http://www.antarctica.ac.uk/data/absl/\n#\n# Key:\n#    ABSLSectorP = Area-average MSLP over ABSL sector (see Fig. 2e)\n#    ActCenPres  = Actual central pressure (i.e., ABSL Minumum MSLP)\n#    RelCenPres  = Relative central pressure (ActCenPres "minus" ABSLSectorP)\n#    ABSL_long   = Longitudinal location of ABSL (degrees East)\n#    ABSL_Lat    = Latitudinal location of ABSL\n#\n\nModel        Year  Month   ABSLSectorP   ActCenPres   RelCenPres    ABSL_long     ABSL_Lat\n'
np.savetxt('test.txt', a, header=header, fmt=('%s, %d, %f, %f'))

Or:

np.savetxt('test.txt', a, fmt='%-12s')

Then you have the column names above the data.

If you wanted, say, two tabs between each element you could do this:

>>> with open('testfile.txt','w') as f:
    f.write('your header string')
    for x in a:
        for y in x:
            f.write(str(y)+'\t\t')
        f.write('\n')

Or, to expand on @Jan Zeiseweis' comment, you could use pandas:

import pandas as pd
pd.DataFrame(a).to_csv('testfile.txt',sep='\t')

I have now found this neat way of including a header using the same formatting as the columned data. Thanks everyone for your help.

import numpy as np
dt = np.dtype([('site', '|S11'), ('year', 'i'), ('dat1', 'd'), ('dat2', 'd')])
a = np.zeros(2, dt)
a['site'] = ['Paris', 'London']
a['year'] = [1979, 1980]
a['dat1'] = [272.4322, 270.36]
a['dat2'] = [2.21, 3.55]

titles = ['Site', 'Year', 'Dat1', 'Dat2']
header = '%-12s %6s %11s %11s' % ( tuple(titles) )
header = ''+header+'\n'
np.savetxt('test.txt', a, comments='', header=header, fmt='%-12s %6i %11.4f %11.4f')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM