3

I'm writing an application that reads an ascii file with fortran-ordered arrays, modifies values, then writes that data back out (in fortran order) in ascii. What is the correct way to read this array into numpy, denote the array is in fortran order, then write the data back out in fortran order?

Assume I have a file with the following ascii text:

0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0

These numbers represent a 2x2x2 array written in fortran order.

The ascii format is a bit more complicated than above. However, suffice it to say the format is not really well suited for using any of the automatic numpy ascii loaders like numpy.loadtxt, etc.

I'm executing a line similar to the following to create the array:

x = numpy.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0], order='F')

I know this is in-efficient and does a lot of extra data copying, etc. I'm more worried about the ordering though.

So, at this point x is ordered in memory like a fortran array, I think. Now, when I export this array should I use numpy.nditer(x, order='F')?

1
  • 1
    If x is already ordered like a Fortran array, order is not needed in nditer (which, by default, iterates in memory order). Commented Jul 22, 2013 at 20:04

2 Answers 2

1

Consider the following:

In [11]: x = numpy.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])

In [12]: xf = x.reshape((2, 2, 2), order='F')

Here, xf is a 2x2x2 Fortran-ordered view onto x. You could modify it and x will change accordingly:

In [22]: xf[0,:,1] = [11, 12]

In [23]: x
Out[23]: array([  0.,   1.,   2.,   3.,  11.,   5.,  12.,   7.])

Exporting x would preserve the original ordering.

Sign up to request clarification or add additional context in comments.

3 Comments

This looks correct. My main problem was I didn't realize doing x.shape = (2,2,2) actually changes the order. I created it with order 'F'. However, when I first created the array it was 1-dimensional so the order doesn't take effect. Thus, changing the shape with .shape = (2,2,2) didn't maintain the fortran ordering.
Is there a way to create an array with a shape AND order at the same time? I don't see this in the API. Probably not a huge deal because I'll just be using the view everywhere, not the original array. So, the data isn't copied twice in this case, just once when creating it and copying from python list.
Don't use numpy tofile though. It always writes C order no matter what order the array is in memory (see manual).
1

Here is what works. The transposition works around the fact that numpy tofile() only knows C order.

import numpy as np
file_path = 'C:/Temp/arr.txt'
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
xf = x.reshape((2, 2, 2), order='F')
xf.T.tofile(file_path, sep=' ') # T is transpose, so it gets written in correct order
xn = np.fromfile(file_path, sep=' ')
xnr = np.reshape(xn, (2,2,2),order='F')
assert (xf==xnr).all()

# show the transpose is necessary
xf.tofile(file_path, sep=' ') # no .T, write in wrong order
xn = np.fromfile(file_path, sep=' ')
xnr = np.reshape(xn, (2,2,2),order='F')
assert (xf==xnr).all()==False

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.