2017-03-04 29 views
3

我在繪製等高線圖。數據格式如下所示。目前,我正在逐行讀取數據並繪製等值線圖,這消耗了大量時間。在Python中加載.Map文件Numpy或Pandas

是否可以將數據加載到Numpy或Pandas中,以便我可以更快地處理數據?單輪廓線的

數據描述:

Single Contour line (Polygon) description

繪圖後,等高線圖的樣子:

Contour Map image

示例數據:

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 

我的代碼:

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

如果您包含了用於獲取已有代碼的簡單版本 –

+0

,那麼這將對您有所幫助。這樣,人們就可以在已有解決方案與其解決方案之間進行運行時間比較。 –

回答

1

既然你沒有給出基準,這裏是一些代碼分析文件,這應該是比較快的時候比較天真的解決方案:

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 

結果:

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

非常感謝。它按我的預期工作,比我的代碼快得多。對不起,我的英語不好。謝謝你糾正它。 –

+0

@BhuvanKumar,你很受歡迎。然而,在所以最好的方式表示感謝是upvote *任何*您認爲有用的問題或答案。在你的問題中,如果其中一個答案非常適合你的問題,你可以將其標記爲接受的答案。有關準則,請參閱[幫助中心](http://stackoverflow.com/help/someone-answers)。 –

相關問題