2017-03-04 5 views
3

Ich versuche, eine Konturkarte zu plotten. Das Datenformat ist unten gezeigt. Momentan lese ich die Daten Zeile für Zeile und zeichne die Konturkarte, die viel Zeit in Anspruch nimmt.Laden .Map-Datei in Python Numpy oder Pandas

Ist es möglich, die Daten in Numpy oder Pandas zu laden, damit ich die Daten schneller verarbeiten kann?

Datenbeschreibung der einzelnen Konturlinie:

Single Contour line (Polygon) description

Nach Plotten, die Konturkarte wie folgt aussieht:

Contour Map image

Beispieldaten:

290.0   7 
339740.0 654429.0 339725.0 654442.0 339710.0 654502.0 
339742.0 654522.0 339787.0 654524.0 339808.0 654477.0 
339740.0 654429.0 
    330.0   15 
336127.0 652358.0 336275.0 652295.0 336472.0 652253.0 
336533.0 652141.0 336575.0 652036.0 336716.0 651899.0 
336726.0 651862.0 336699.0 651784.0 336519.0 651649.0 
336422.0 651568.0 336372.0 651463.0 336279.0 651393.0 
336167.0 651335.0 336227.0 651293.0 336385.0 651076.0 
    310.0   21 
338229.0 651803.0 338379.0 651945.0 338511.0 652046.0 
338623.0 652069.0 338696.0 652044.0 338718.0 651994.0 
338724.0 651914.0 338781.0 651942.0 338846.0 652037.0 
338883.0 652100.0 338955.0 652182.0 339078.0 652230.0 
339345.0 652411.0 339460.0 652539.0 339537.0 652549.0 
339590.0 652549.0 339670.0 652539.0 339717.0 652487.0 
339698.0 652379.0 339648.0 652294.0 339616.0 652024.0 
    340.0   13 
338384.0 651871.0 338486.0 651939.0 338538.0 651936.0 
338586.0 651886.0 338596.0 651824.0 338664.0 651799.0 
338779.0 651837.0 338949.0 652014.0 339220.0 652241.0 
339475.0 652394.0 339533.0 652381.0 339575.0 652246.0 
339571.0 652111.0 
    360.0   5 
339945.0 651435.0 339920.0 651465.0 339970.0 651482.0 
339987.0 651455.0 339945.0 651435.0 

Mein Code:

def ReadMapFile(mapfile): 

    linesCountMapFile = sum(1 for line in open(mapfile)) 
    #open the map file 
    file = open(mapfile, 'r') 
    LoadCoord = False 
    Ecount = 0 
    #process the file line by line 
    j = 0 
    m={} 
    n={} 
    o={} 
    X = [] 
    Y = [] 
    Z = [] 
    xx = [] 
    yy = [] 
    for mindex, line in enumerate(file): 

     #ignore the first 4 line 
     if mindex > 3: 
      #Extract the Contour points 
      if len(line) > 0 and LoadCoord == True: 
       XY = line.split(" ") 
       XY = [c for c in XY if c] 
       for index, coord in enumerate(XY): 
        if index % 2 == 0: 
         xx.append(float(coord.strip())) 
        else: 
         yy.append(float(coord.strip())) 
       if len(xx) == Ecount: 
        LoadCoord =False 
        X = xx 
        Y = yy 
        #Percentage of map loaded 
        print round((float(mindex)/float(linesCountMapFile))*100,2) 
        m[j]=X 
        n[j]=Y 
        o[j]=Z[0] 

        #Add XYZ to plot window 
        #addXYZ(X, Y, Z) 

        xx = [] 
        yy = [] 
        j = j+1 

      #Extract the elevation of the map 
      if len(line) == 24 and LoadCoord == False: 
       Elevation = line.split(" ") 
       Elevation = [z for z in Elevation if z] 
       if len(Elevation[1]) < 6: 
        E = float(Elevation[0].strip()) 
        Ecount = int(Elevation[1]) 
        ZVal = [E]*(Ecount) 
        #Z.append(ZVal) 
        Z = ZVal #.append(ZVal) 
        #print Z 
        LoadCoord = True 

    file.close() 

    ConX = m 
    ConY = n 
    ConZ = o 
    #Return Dictionary of X, Y, Z 
    return ConX, ConY, ConZ 
d = ReadMapFile("Test.map") 

print d 
+0

Es wäre hilfreich, wenn Sie eine einfache Version des Codes enthalten, den Sie verwendet haben, um das zu erhalten, was Sie bereits haben –

+0

Auf diese Weise könnten Benutzer einen Laufzeitvergleich zwischen der bereits vorhandenen Lösung und ihrer Lösung durchführen. –

Antwort

1

Da Sie keine Grundlinie gab, hier einige Code, um Ihre Datei zu analysieren, die relativ schnell im Vergleich zu naiven Lösungen sein sollte:

import struct 
import pandas as pd 

fieldwidths = (
    (8, 12), 
    (8, 12, 12, 12), 
    (8, 12, 12, 12, 12, 12), 
) 
fmtstrings = [ 
    ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's') 
      for fw in fieldwidth) for fieldwidth in fieldwidths] 
fieldstructs = [struct.Struct(fmtstring) for fmtstring in fmtstrings] 
parsers = [fieldstruct.unpack_from for fieldstruct in fieldstructs] 

def get_contours(filename): 
    contours = [] 
    points = [] 
    with open(filename, 'rb') as f: 
     points_left = 0 
     for line in f: 
      if points_left >= 3: 
       x1, y1, x2, y2, x3, y3 = parsers[2](line) 
       points.append((float(x1), float(y1))) 
       points.append((float(x2), float(y2))) 
       points.append((float(x3), float(y3))) 
       points_left -= 3 

      elif points_left == 2: 
       x1, y1, x2, y2 = parsers[1](line) 
       points.append((float(x1), float(y1))) 
       points.append((float(x2), float(y2))) 
       points_left = 0 

      elif points_left == 1: 
       x, y = parsers[0](line) 
       points.append((float(x), float(y))) 
       points_left = 0 

      else: 
       elevation, length = parsers[0](line) 
       elevation = float(elevation) 
       points_left = int(length) 
       points = [] 

      if points_left == 0: 
       contours.append(pd.Series(points, name=elevation)) 

     return contours 

Ergebnisse:

0 (339740.0, 654429.0) 
1 (339725.0, 654442.0) 
2 (339710.0, 654502.0) 
3 (339742.0, 654522.0) 
4 (339787.0, 654524.0) 
5 (339808.0, 654477.0) 
6 (339740.0, 654429.0) 
Name: 290.0, dtype: object 

0  (336127.0, 652358.0) 
1  (336275.0, 652295.0) 
2  (336472.0, 652253.0) 
3  (336533.0, 652141.0) 
4  (336575.0, 652036.0) 
5  (336716.0, 651899.0) 
6  (336726.0, 651862.0) 
7  (336699.0, 651784.0) 
8  (336519.0, 651649.0) 
9  (336422.0, 651568.0) 
10 (336372.0, 651463.0) 
11 (336279.0, 651393.0) 
12 (336167.0, 651335.0) 
13 (336227.0, 651293.0) 
14 (336385.0, 651076.0) 
Name: 330.0, dtype: object 

.... 
+0

Vielen Dank. Es funktioniert wie erwartet und viel schneller als mein Code. Entschuldigung für mein schlechtes Englisch. Danke für die Korrektur. –

+0

@BhuvanKumar, Sie sind herzlich willkommen. Auf dem besten Weg jedoch, so vielen Dank zu sagen, ist es, * alle * Fragen oder Antworten zu verbessern, die Sie nützlich finden. Und wenn eine Ihrer Antworten für Ihr Problem gut geeignet ist, können Sie sie als akzeptierte Antwort markieren. Weitere Informationen finden Sie in der [Hilfe] (http://stackoverflow.com/help/someone-answers). –

Verwandte Themen