[SciPy-dev] Input value from data file to 2D array

Gabriel Gellner ggellner@uoguelph...
Fri Apr 18 00:51:39 CDT 2008

> First, here is my Fortran code.
> DIMENSION A(10,10), B(10,10)
> OPEN(21,FILE='aaa.dat')
> DO 10 K=1,2
> READ(21,1602) ((A(I,J),J=1,3),I=1,2)
> READ(21,1602) ((B(I,J),J=1,3),I=1,2)
> WRITE(6,1602) ((A(I,J),J=1,3),I=1,2)
> WRITE(6,1602) ((B(I,J),J=1,3),I=1,2)
> 1602 FORMAT(3I4)
> and aaa.dat file is
> 0 1 1
> 1 1 1
> 2 1 1
>  ; ; ;
> ; ; ;
> 18 1 1
> 19 1 1
> The code is going to read each value of the data file(aaa.dat)
> and input the value to the array A, B. According the "DO 10 K=1,2"
> which means a loop of Fortran it is going to try to read 1st 2x3 array
> and set them to A, also read 2nd 2x3 array to B.
> Two "WRITE(6,1602) "s mean that the final value of array A and B are
> 3rd 2x3 array adn 4th 2x3 array
>   4 1 1
> 5 1 1
> 6 1 1
> 7 1 1
> Question 1: How to input value from data file to 2D array ?
> Can I write code like following ?
>  a=zeros([2,3], Float)
First you don't need to use Float unless you a using a really old version of
numpy just write

a = zeros((2, 3))

Also, it is good to pass a tuple not a list as passing a mutable argument is asking
for trouble, even though in this case it is safe.

>     for i in range(1,2):
>     for j in range(1,3):
>     a[i][j]=i,j
Remember that python has 0 based arrays so you would want to write

for i in range(2):
    for j in range(3):
        a[i, j] = <some value at the i, j index>

so that range(2) returns the indices 0, 1
and     range(3) returns the indices 0, 1, 2
otherwise you are asking for out of bounds exceptions.
Also notice that numpy arrays are indexed using comma's to separate the
dimensions, unlike nested lists in regular python or C.
> (If the size of data file is very big , using
> read_array() or fromfile() will be very hard. )
Maybe not, as most file objects return iterators so they don't read in the
entire file into memory, try it the ugly way first, you might be surprised.
That is you can usually just iterate over the file like

for line in open('aaa.dat'):
    print line.split()

to print out each line split by spaces, and the open statement will just
return an iterator, not read the entire file into memory. To read the entire
file into memory you would do (not that you really want to do this):

for line in open('aaa.dat').readlines():
    print line.split()

> Question 2: Such like "DO 10 K=1,1500", I just read a part of
> data file(<=very big file). How cat write this with Python ?
Using the above iterator method I would do
for lnum, line in enumerate(open('aaa.dat')):
    if lnum >= 1500:
    print line.split()

or if you don't like the break

file = open('aaa.dat')
for k in range(1500):
    line = file.read()
    <do something with the line>

Okay so with all this information lets try doing your problem.

import numpy

a = numpy.zeros((10, 10))
b = numpy.zeros((10, 10))

file = open('aaa.dat')
for k in range(2):
    for i in range(2):
        a[k + i, :3] = [int(line) for line in file.read().strip().split()]
    for i in range(2):
        b[k + i, :3] = [int(line) for line in file.read().strip().split()]

Which is from the best I can make out the porting of your fortran code (the
reading part, the writing is similiar), though it seems like A, B are to big,
that is you make the dimensions of the arrays much larger than you use both
the number of rows and columns. Maybe I misunderstand your code. Hopefully
this helps a little. 

And finally welcome to the wonderful world of python!


More information about the Scipy-dev mailing list