2

I have a question regarding formatting. I am trying to extract relevant data and insert this data into a fortran file. Thankfully, I am using python to accomplish this task. It just so happens that the fortran file is sensitive to the number of spaces between text. So, this brings me to my question. My array array data looks like:

    [[ -1.80251269  12.14048223  15.47522331]
     [ -2.63865822  13.1656285   15.97462801]
     [ -1.76966256  11.35311123  16.13958474]
     [ -0.76320052  12.45171386  15.34209158]
     [ -2.12634889  11.84315415  14.48020468]]
    [[-14.80251269   1.14048223   1.47522331]
     [ -2.63865822  13.1656285   15.97462801]
     [ -1.76966256  11.35311123  16.13958474]
     [ -0.76320052  12.45171386  15.34209158]
     [ -2.12634889  11.84315415  14.48020468]]
    [[ -0.80251269   0.14048223   0.47522331]
     [ -2.63865822  13.1656285   15.97462801]
     [ -1.76966256  11.35311123  16.13958474]
     [ -0.76320052  12.45171386  15.34209158]
     [ -2.12634889  11.84315415  14.48020468]]

These elements are floats, not strings. For example, I wanted the the first row (and every row thereafter) of the data to look like:

     -1.80251269     12.14048223     15.47522331

How would I accomplish this? To be specific, there are 5 white spaces that seperate the left margin from the 1st number, -1.80251269, and 5 white spaces that seperate each of the three numbers. Notice also that I need the array brackets gone, but I suspect I can do this with a trim function. Sorry for my lack of knowledge guys; I do not even know how to begin this problem as my knowledge in Python syntax is limited. Any help or tips would be appreciated. Thanks!

EDIT: this is the code I am using to generate the array:

     fo = np.genfromtxt("multlines.inp")
     data=scipy.delete(fo, 0, 1)
     txt = np.hsplit(data,3)
     all_data = np.vsplit(data, 4)
     i=0
     num_molecules = int(raw_input("Enter the number of molecules: "))
     print "List of unaltered coordinates:"
     while i < (num_molecules):
          print all_data[i]
Rob
  • 26,989
  • 16
  • 82
  • 98
zww
  • 91
  • 2
  • 8
  • We'll need to see your code to be able to help you make it work. Also, tagging both python-2.7 and python-3.x makes it a bit hard to know what you are using - only tag with the version you are using (if you can use either, you can only give the general python tag, and ignore the version ones altogether). – Gareth Latty Jun 12 '15 at 15:15
  • Is this data in a file.txt for example or part of your code?...because if it is part of your, then what type of data is that? – Iron Fist Jun 12 '15 at 15:29
  • You need to look into [str.ljust](https://docs.python.org/2/library/stdtypes.html#str.ljust) and [str.rjust](https://docs.python.org/2/library/stdtypes.html#str.rjust). – Rick Jun 12 '15 at 15:31
  • Also: possible duplicate of http://stackoverflow.com/questions/14776788/python-how-can-i-pad-a-string-with-spaces-from-the-right-and-left – Rick Jun 12 '15 at 15:32
  • TypeError: unsupported operand type(s) for +: 'numpy.float64' and 'str' I get this error when I implement user kamik423 code. I am assuming this means we can't combine strings with floats? thoughts? – zww Jun 12 '15 at 15:37

5 Answers5

2

If you are using NumPy, you can use np.savetxt:

np.savetxt('a.txt', a.reshape(15,3), '%16.8f')

To get

     -1.80251269      12.14048223      15.47522331
     -2.63865822      13.16562850      15.97462801
     -1.76966256      11.35311123      16.13958474
     ...

(You need to reshape your array into 2-dimensions to do what I think you want).

xnx
  • 24,509
  • 11
  • 70
  • 109
  • I am trying to insert this code into code I have already written that gives the output I put in my original post. Should I trying to insert the output of the code I have already written into a .txt file and use your method? Would this be easiest? – zww Jun 12 '15 at 15:41
  • I'm not sure I understand, but would it be easiest to simply replace the code you wrote to produce the output you give (with square brackets, etc) with the command in my answer? – xnx Jun 12 '15 at 15:49
  • I am trying your way, however I am only getting the last part of the array saved in the .txt file starting with: [[ -0.80251269 0.14048223 0.47522331] Sorry, for formatting issues, I guess comments are as nice as posts. Anyway, could you go into more detail of what the different elements of the np.savetxt do, because the numpy website doesnt go into much detail but I feel like this is what I want. – zww Jun 12 '15 at 16:09
  • Perhaps the array you're passing as `a` isn't what I think it is: perhaps you could post your code for this part and double-check the contents of `a`. – xnx Jun 12 '15 at 16:12
  • fo = np.genfromtxt("multlines.inp") data=scipy.delete(fo, 0, 1) txt = np.hsplit(data,3) #print txt all_data = np.vsplit(data, 4) while i < (num_molecules): print all_data[i] – zww Jun 12 '15 at 16:14
  • I will edit my original post so that formatting isnt an issue – zww Jun 12 '15 at 16:15
  • Do you want a separate file for each molecule? If so, and `all_data[i]` is already two-dimensional, simply `np.savetxt(filename, '%16.8f')` where filename is different for each molecule. – xnx Jun 12 '15 at 16:20
  • I want all the molecules together in one file. Ideas on how this can be done? And I would still need to add add_data[i] in the np.savetxt function right? – zww Jun 12 '15 at 16:21
  • Then don't loop over `num_molecules`, use `np.savetxt(filename, all_data.reshape(nrows,3), '%16.8f')` where `nrows = 3 * num_molecules` – xnx Jun 12 '15 at 16:25
  • TypeError: 'list' object is not callable I get this error. I need the loop because I must operate on these coordinate to obtain the center of mass. I have inserted your block of code outside the loop. Is there something I am overlooking? – zww Jun 12 '15 at 16:32
  • This line: `all_data = np.vsplit(data, 4)` splits your data into a `list` of 4 numpy arrays (does this mean you have 4 molecules?). But the `data` array you give in your question has 3 blocks... so I'm confused. – xnx Jun 12 '15 at 16:41
1

If you have your data formatted as a list, then I suspect that @kamik423's answer will help you. If it if formatted as a string, you may wish to try something like the following.

def properly_format(line):
    nums = line.strip(' []\t').split() 
    spaces = '     '
    return spaces + nums[0] + spaces + nums[1] + spaces + nums[2]

lines = my_array_string.splitlines() #if your data is a multiline string
for line in lines:
    formatted_line = properly_format(line)
    # do something with formatted_line

Edit: forgot to split the string.

Blair
  • 6,623
  • 1
  • 36
  • 42
0

If you don't care about the length of each block you can just do

for i in whateverYouArrayIsCalled:
    print str(i[0]) + "    " + str(i[1]) + "    " + str(i[2])

if you however want to have all the elements to be inline try

for i in whateverYouArrayIsCalled:
    print (str(i[0]) + "    ")[:20] + (str(i[1]) + "    ")[:20] + str(i[2])

where the 20 is the length of each block

(for 2.7)

Hans
  • 2,354
  • 3
  • 25
  • 35
  • Is the period supposed to be there? – zww Jun 12 '15 at 15:25
  • TypeError: unsupported operand type(s) for +: 'numpy.float64' and 'str' I get this error. Does this mean that I must convert my float data type to a string before I insert blank space? – zww Jun 12 '15 at 15:27
0

I will assume that the data array is saved in a data.txt file and you want to save the result into fortran.txt, then:

    fortran_file = open('fortran.txt','w') # Open fortran.txt for writing

    with open('data.txt',r) as data_file: #Open data.txt for reading

            while True:
                line = data_file.readline()
                if not line: break # EOF
                result = line.strip('[]').split()
                result = "     " + "     ".join(result)
                fortran_file.write(result)

    fortran_file.close()
Iron Fist
  • 10,739
  • 2
  • 18
  • 34
0

try this:

import numpy


numpy.set_printoptions(sign=' ')
pppery
  • 3,731
  • 22
  • 33
  • 46
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. –  Jul 07 '20 at 15:37