Specific column widths and alignment with savetxt

我是研究僧i 提交于 2019-12-10 22:49:44

问题


I'm nearly finished with this program, but I can't get the output quite how I want it. Here is the code:

import numpy as np

filename = (raw_input("Which file are we loading?  "))
header = input("How many header lines?  ")

# Input variables for column numbers and limiting factors

pcol = input("What column number is parallax in?  ")
vcol = input("What column number is Vmag (or other limiting mag) in?  ")
pmcol = input("What column number does proper motion begin in (Mu/PA or MuRa MuDec format)  ")
ra = input("What column number is RA1 in? (h m s format)  ")
dec = input("What column number is Dec1 in? (d m s format)  ")
maglim = input("What is your limiting (dimmest) magnitude?  ")
parlim = input("What is your limiting (farthest) parallax?  ")

# Read in entire file

data = np.loadtxt(filename,skiprows=header,dtype=str)

# Select correct columns

parallax_str = data[:,pcol-1] 
ra1_str = data[:,(ra-1)]
ra2_str = data[:,(ra)]
ra3_str = data[:,(ra+1)]
dec1_str = data[:,(dec-1)]
dec2_str = data[:,(dec)]
dec3_str = data[:,(dec+1)]
vmag_str = data[:,vcol-1]
pm1_str = data[:,(pmcol-1)]
pm2_str = data[:,(pmcol)]

# Convert selected strings to floats

parallax = parallax_str.astype(float)
vmag = vmag_str.astype(float)
pm1 = pm1_str.astype(float)
pm2 = pm2_str.astype(float)

criteria = (parallax>=parlim) & (vmag<=maglim)
vmag = vmag[criteria]
parallax = parallax[criteria]
pm1 = pm1[criteria]
pm2 = pm2[criteria]
ra1_str = ra1_str[criteria]
ra2_str = ra2_str[criteria]
ra3_str = ra3_str[criteria]
dec1_str = dec1_str[criteria]
dec2_str = dec2_str[criteria]
dec3_str = dec3_str[criteria]


newlist = np.vstack((ra1_str,ra2_str,ra3_str,dec1_str,dec2_str,dec3_str,vmag,parallax,pm1,pm2))
newlist = newlist.T

np.savetxt('observe.list',newlist,fmt='%s')

Now, this gives me a file that looks like this:

00 19 05.563 -09 57 53.47 9.92 47.43 -35.62 -301.99
00 24 25.933 -27 01 36.38 7.91 54.87 665.64 83.67
00 39 21.806 +21 15 01.71 5.87 90.42 -461.32 -370.02
00 45 04.894 +01 47 07.88 8.01 46.37 -49.08 -573.23
00 48 22.977 +05 16 50.21 5.72 134.14 757.11 -1141.33
00 51 21.754 +18 44 21.31 9.21 46.79 54.1 -267.14

However, I want a file that looks like this:

00 19 05.563 -09 57 53.47 9.92  47.43  -35.62  -301.99
00 24 25.933 -27 01 36.38 7.91  54.87  665.64    83.67
00 39 21.806 +21 15 01.71 5.87  90.42 -461.32  -370.02
00 45 04.894 +01 47 07.88 8.01  46.37  -49.08  -573.23
00 48 22.977 +05 16 50.21 5.72 134.14  757.11 -1141.33
00 51 21.754 +18 44 21.31 9.21  46.79   54.10  -267.14

Such that everything is right aligned. Can anyone help me figure out an efficient way to do this?

Cheers.


回答1:


You can make different formats for each column by passing a sequence to the 'fmt' keyword argument. Three examples below show different options. More info available at docs.scipy.org.

>>> import numpy as np
>>> a = np.random.random((3,4))
>>> a[1] = a[1] + 10
>>> a
array([[  0.66860114,   0.29021582,   0.47168711,   0.86839242],
       [ 10.41030497,  10.22771623,  10.80389801,  10.6170771 ],
       [  0.47201727,   0.90861352,   0.03952651,   0.67245859]])
>>>
>>> # saved using string format
>>>
>>> np.savetxt('string.txt', a, fmt='%s')
>>> with open('string.txt','r') as f: print(f.read())
...
0.668601144977 0.290215822112 0.471687110847 0.86839242197
10.4103049716 10.2277162318 10.8038980106 10.617077099
0.472017270547 0.9086135154 0.0395265080276 0.672458588797
>>>
>>> # saved using floating format with the "width" parameter = 10
>>>
>>> np.savetxt('fixed.txt',a, fmt='%10.4f')
>>> with open('fixed.txt','r') as f: print(f.read())
...     
    0.6686     0.2902     0.4717     0.8684
   10.4103    10.2277    10.8039    10.6171
    0.4720     0.9086     0.0395     0.6725
>>> 
>>> # saved using format specifier sequence with format for each column
>>> 
>>> np.savetxt('multi.txt',a, fmt=('%5.2f', '%10.4f', '%7.3f', '%12.1f'))
>>> with open('multi.txt','r') as f: print(f.read())
... 
 0.67     0.2902   0.472          0.9
10.41    10.2277  10.804         10.6
 0.47     0.9086   0.040          0.7



回答2:


What you want to achieve is a so called 'fixed-width' csv-file. Since neither numpy nor pandas is able to export data to a csv-file formatted like this you could do a workaround using the format specifier of numpy.savetext() if you know the number of digits you have to handle:

#!/usr/bin/env python3
# coding: utf-8

import numpy as np

# generate a random array to get some sample data
newlist = np.random.rand(3,2)

# assume you have three decimal digits and seven in total (so four in front of the decimal sign)
np.savetxt('observe.list', newlist, fmt='%7.3f')

Giving:

  0.021   0.571
  0.471   0.416
  0.177   0.720

Update due to comment:

newlist = np.array([1.5, 10.55555, 0.3, 2, 5.0])
np.savetxt('observe.list', newlist, fmt='%10.5f')

Giving:

   1.50000
  10.55555
   0.30000
   2.00000
   5.00000


来源:https://stackoverflow.com/questions/34010451/specific-column-widths-and-alignment-with-savetxt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!