Search code examples
arrayspython-3.xtypeconvertervalueconverter

Converting string array to float array


I'm trying to read some simulation results from .dat-files and to analyze them. The files have following structure:

 N o d a l   D i s p l a c e m e n t s     Time       0.10000E+01
                                            Prop. Ld.  1.00000E+00

Node     1 Coord     2 Coord     3 Coord     1 Displ     2 Displ     3 Displ
   1  0.0000E+00  5.0000E-01  0.0000E+00  0.0000E+00  0.0000E+00  0.0000E+00

   2  0.0000E+00  2.5005E-01  0.0000E+00  0.0000E+00  0.0000E+00  0.0000E+00

   3  0.0000E+00  1.0000E-04  0.0000E+00  0.0000E+00  0.0000E+00  0.0000E+00
   4  1.0000E+00  5.0000E-01  0.0000E+00 -1.9511E-04  4.0845E-04 -2.1522E-05

   5  1.0000E+00  2.5005E-01  0.0000E+00  1.1185E-08  4.0053E-04  2.6545E-09

   6  1.0000E+00  1.0000E-04  0.0000E+00  1.9511E-04  4.0847E-04  2.1526E-05

   7  2.0000E+00  5.0000E-01  0.0000E+00 -3.5177E-04  1.5287E-03 -1.2678E-05

... and so one.

How can i convert the numerical data to float and delete the strings? I tried it with following code:

class DataLoader:
    def __init__(self, number_files):
        self.number_files = number_files

    def loader(self):
        array = []

        for i in range(1, self.number_files + 1):
            try:
                if i < 10:
                    data = open("ndis_00%s.dat" % i, "r")
                elif i >= 10 and i <= 100:
                    data = open("ndis_0%s.dat" % i, "r")
            except IOError:
                print("I/O Error")

            for line in data:
                if line != "\n":
                    array.append(line.split())
                    try:
                        float(line)
                    except (ValueError, TypeError):
                        line[:] = []
                    print(line)

In the code I want to keep the lines that convert to float and the string that does not convert can be completely deleted.


Solution

  • If the files are really structured as above, the lines that contain the data that you want are nonempty and don't begin with an alphabetical character. You can exploit that as follows:

    def extractData(f):
        data = []
        for line in f:
            line = line.strip()
            if len(line) == 0 or line[0].isalpha(): continue
            items = line.split()
            data.append([float(item) for item in items[1:]])
        return data
    

    The above function takes such a file and returns a 2-dimensional Python array (list of lists) containing the float data that you are interested in.

    To test (where test.dat contains your sample data):

    with open('test.dat') as testf:
        nums = extractData(testf)
        for row in nums: print(row)
    

    Output:

    [0.0, 0.5, 0.0, 0.0, 0.0, 0.0]
    [0.0, 0.25005, 0.0, 0.0, 0.0, 0.0]
    [0.0, 0.0001, 0.0, 0.0, 0.0, 0.0]
    [1.0, 0.5, 0.0, -0.00019511, 0.00040845, -2.1522e-05]
    [1.0, 0.25005, 0.0, 1.1185e-08, 0.00040053, 2.6545e-09]
    [1.0, 0.0001, 0.0, 0.00019511, 0.00040847, 2.1526e-05]
    [2.0, 0.5, 0.0, -0.00035177, 0.0015287, -1.2678e-05]
    

    If this doesn't work -- you haven't adequately defined the structure of your files.