Python: как избежать цикла, который вызывает две функции? - PullRequest
1 голос
/ 27 мая 2019

Я загрузил изображение geottif, содержащее население Гаити, с worldpop.org .

Изображение можно загрузить с здесь

from osgeo import gdal
import matplotlib.pyplot as plt
from matplotlib import cm

fileO = 'HTI_ppp_v2b_2015_UNadj_32618.tif'
geo = gdal.Open(fileO)
topo = geo.ReadAsArray()
i, j = np.where(topo>0)
topo = topo[min(i):max(i)+1, min(j):max(j)+1]
topo[topo<0] = np.nan

fig = plt.figure(frameon=False)
plt.imshow(topo, cmap=cm.BrBG_r)
plt.axis('off')
cbar = plt.colorbar(shrink=0.75)
cbar.set_label('meters')
plt.show()

enter image description here

Я хотел бы присвоить каждому значению координату, то есть координаты центроида пикселя, и иметь кадр данных, подобный следующему

df_coord:
    X_centr   Y_centr   Pop
0   650000    2050000   54   
1   556000    2250000   NaN 

Это то, что я делаю, но процесс занимает слишком много времени.

import affine
import pandas as pd


def retrieve_pixel_value(geo_coord, data_source):
    """Return floating-point value that corresponds to given point."""
    x, y = geo_coord[0], geo_coord[1]
    forward_transform =  \
        affine.Affine.from_gdal(*data_source.GetGeoTransform())
    reverse_transform = ~forward_transform
    px, py = reverse_transform * (x, y)
    px, py = int(px + 0.5), int(py + 0.5)
    pixel_coord = px, py

    data_array = np.array(data_source.GetRasterBand(1).ReadAsArray())
    return data_array[pixel_coord[0]][pixel_coord[1]]
def pixel2coord(col, row):
    """Returns global coordinates to pixel center using base-0 raster index"""
    xp = a * col + b * row + a * 0.5 + b * 0.5 + c
    yp = d * col + e * row + d * 0.5 + e * 0.5 + f
    return(xp, yp)

fileO = 'HTI_ppp_v2b_2015_UNadj_32618.tif'
geo = gdal.Open(fileO)
topo = geo.ReadAsArray()
i, j = np.where(topo>0)
topo = topo[min(i):max(i)+1, min(j):max(j)+1]

x_coord = []
y_coord = []
val = []
for idx in range(0,len(i)):
    ii = i[idx]
    jj = j[idx]
    coords = pixel2coord(ii, jj)  ## find coordinates of the pixel
    x_coord.append(coords[0])      
    y_coord.append(coords[1])
    pop = retrieve_pixel_value(coords, geo) ## retrieve pixel value at given coordinates - coords
    val.append(pop)

import pandas as pd
df_coord = pd.DataFrame()
df_coord['X_coord'] = ii
df_coord['Y_coord'] = jj
df_coord['Pop'] = val

Можно ли сделать то же самое без цикла?

...