2 votos

Leer sólo filas específicas de un shapefile con GeoPandas / Fiona

Me gustaría leer sólo ciertas filas de un shapefile utilizando GeoPandas. He leído un enfoque para limitar las columnas del shapefile a leer, que también podría utilizar ( Leer sólo columnas de atributos específicos de un shapefile con Geopandas / Fiona ), pero estaba buscando ayuda para traducir este enfoque para limitar las filas del shapefile que se está leyendo.

Creo que la respuesta es una simple modificación de GeoDataFrame.from_features y una función que utiliza Fiona en las preguntas vinculadas sobre la limitación de las columnas del shapefile para leer en GeoPandas.

7voto

GreyCat Puntos 146

Si no quieres leer todo el archivo, otra solución es utilizar un generador como en Leer sólo columnas de atributos específicos de un shapefile con Geopandas / Fiona

Como recordatorio (de ¿Qué hace la palabra clave "yield"? ):

  • Todo lo que puede utilizar "for... en..." es un iterable: listas, cadenas, archivos... pero almacena todos los valores en memoria
  • Los generadores son iterables, pero sólo se pueden leer una vez. Esto se debe a que no almacenan todos los valores en memoria, sino que generan los valores sobre la marcha

Cuando se utiliza Fiona para leer un shapefile, el resultado es un generador y no una simple lista y con la lista de filas [0,4,7], no necesitamos leer todos los registros del shapefile sino sólo hasta el último elemento de la lista.

El generador

def records(filename, list):
    list = sorted(list) # if the elements of the list are not sorted
    with fiona.open(filename) as source:
        for i, feature in enumerate(source[:max(list)+1]):
            if i in list:
                yield feature
 gpd.GeoDataFrame.from_features(records("test.shp", [4,0,7]))

Resultado

enter image description here

También es posible adaptar la solución de rick debbout convirtiendo la comprensión de la lista (creará primero toda la lista en memoria) en expresión generadora (creará los elementos sobre la marcha)

def getRows2(fn, idxList):
    reader = fiona.open(fn)
    return gpd.GeoDataFrame.from_features((reader[x] for x in idxList))

Y si se quiere extraer una porción continua, de 8 a 12 por ejemplo, es más fácil

c = fiona.open('test.shp')
gpd.GeoDataFrame.from_features(c[8:13])

enter image description here

4voto

Ari Raju Puntos 21

Utilizando los índices podrías:

import fiona
import geopandas as gpd

def getRows(fn, idxList):
    reader = fiona.open(fn)
    return gpd.GeoDataFrame.from_features([reader[x] for x in idxList])

keepIndexes = [0,4,7]  # list of indexes from shp file
filename = './path/to/filename'
outDF = getRows(filename, keepIndexes)

Creo que si usted fuera a utilizar los valores de una columna para seleccionar, como usted enlazó arriba, usted tendría que leer a través de todo el archivo para obtenerlos de todos modos, así que, no hay diferencia en el tiempo de lectura.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X