Carga de Bases de Datos JSON desde GCP en Google Colab
Resumen
A continuación vamos a cargar una base de datos en formato JSON que estará almacenada en GCP (Google Cloud Platform). Trabajaremos sobre Google Colab. Crea un Notebook, configúralo y prepárate.
Cómo descargar bases de datos desde la web
Para esta ocasión usaremos la librería os y zipfile para la manipulación y procesamiento del dataset.
import os
import zipfile
Descargaremos el repositorio desde la locación en GCP, usaremos el comando wget para extraer el archivo, agregaremos la opción —no-check-certificate para omitir certificaciones y guardaremos la salida en la carpeta tmp con el nombre databasesLoadData.zip.
Obtendremos la locación del archivo comprimido y crearemos una referencia en memoria con una instancia zipfile en modo lectura, posteriormente extraeremos el contenido y lo nombraremos de la misma manera sin extensión dado que será un directorio. Finalmente cerramos la instancia y tendremos nuestro dataset inicial listo para manipular.
Si navegamos en el directorio de archivos, podremos explorar el contenido de nuestra descarga, tendrá 4 carpetas, donde las 2 más importantes serán las de base64 (a trabajar próximamente) y la de formato JSON.
Si nos adentramos al contenido del dataset en formato JSON, encontraremos con objetos con 2 claves diferentes: Content (que contiene el link de la imagen) y label (que expresa la letra a la que se refiere).
Para el procesamiento del dataset haremos uso de varios módulos de Python, donde JSON, codecs, requests y bytesIO nos ayudarán al proceso de peticiones mientras que el resto nos serán útiles a nivel de manipulación y representación.
Creamos un array donde guardaremos los JSON, posteriormente abriremos el archivo, lo recorreremos línea a línea y lo guardaremos en formato de diccionario, finalmente, verificamos la cantidad de imágenes encontradas correlacionando el tamaño del array.
data_json =[]with codecs.open(url,"rU","utf-8")asjs:for line injs: data_json.append(json.loads(line))print(f'{len(data_json)} imagenes encontradas')
Si verificamos el contenido nos encontraremos con un diccionario con las claves content y label y su respectivos valores.
Con los datos aislados, podemos descargar cada imagen, por lo que haremos una petición HTTP, la encapsularemos en un objeto BytesIO, será interpretado como una imagen y finalmente se transformará en un array de Numpy.
Guardaremos en la lista de imágenes un array de 2 elementos donde el primero será la representación matricial de la imagen y el segundo la etiqueta.
images =[]for data in data_json: response = requests.get(data["content"]) img = np.asarray(Image.open(BytesIO(response.content))) images.append([img, data["label"]])
Para verificar la integridad del contenido lo mostraremos en pantalla con matplotlib, donde tomaremos la imagen y la redimensionaremos al tamaño esperado (de ser requerido), paralelamente tomaremos la etiqueta y las obtendremos ambas en pantalla.
Me pareció importante entender esta parte en cada línea.
Muy enganchado con el curso. Ya tuve algunas clases con Adonai en otros programas de aprendizaje, avanza a buen ritmo sin pasar por alto lo importante.
images =[]# leemos el valor de content y el label de cada línea de la lista que creamos for data in data_json:# creamos una petición accediendo con request para poder ver el contenido de ellas de GCP response = requests.get(data['content'])# convertimos las imagenes en array# abrimos la imagen con PIL # convertimos la imagen en un BytesIO ya que está decodificada img = np.asarray(Image.open(BytesIO(response.content)))# guardamos la imagen en BytesIO y el labol en la lista images images.append([img, data['label']])
Muchas gracias por el aporte German, estoy seguro que les servira a muchos estudiantes, saludos!
++¿QUÉ VIMOS EN ÉSTA CLASE?++
Descargar la base de datos comprimirda y descomprimirla luego para cargarla a Google Cloud Platform (GCP) y poder acceder mediante una URL
El primer paso es importar dos librerías de python
import os # para trabajar con sistemas operativos
import zipfile # para manipular comprimidos
Después en la terminal de tu sistema operativo ejecuta !wget --no-check-certification o curl -k que nos permite poder descargar sin ningún requerimiento ni errores de SSL
# PARALINUX!wget --no-check-certificate https://storage.googleapis.com/platzi-tf2/databasesLoadData.zip-O/tmp/databasesLoadData.zip# PARAWINDOWScurl -k -o /c/Users/admin/Downloads/databasesLoadData.zip https://storage.googleapis.com/platzi-tf2/databasesLoadData.zip# Esto es para descargar la base de datos del proyecto en un .zip
Luego de de descargarla podemos acceder a ella con python y descomprimirla si estás trabajando en Google Colab, si en cambio estás en tu local puedes omitir este paso:
zip_path ="/tmp/databasesLoadData.zip" # "C:/Users/admin/Downloads"for windows
zip_ref = zipfile.ZipFile(zip_path,"r") # ZipFile() metodo para ABRIR una instancia del fichero
zip_ref.extractall("/tmp/databasesLoadData.zip") # acceder al método extraerall los archivos y descomprimir
zip_ref.close() # CERRAR la instancia del fichero
Ahora hay que leer la bases de datos:
Leer la base de datos en JSON
Se debe guardar la ubicación el fichero en una variable
Se debe deserializar el archivo JSON (convertir los objetos a cadenas de texto)
2.1. Debemos abrir el archivo y leer cada linea agregandola como elemento a un array
Recorrer cada imágen y su label en el JSON y hacer una petición GET a la imágen
3.1. Guardar la imágen y el label en cada indice de un array
Ver la imágen
# 1import json
import codecs
import requests
import numpy as np
fromPILimportImagefrom io importBytesIOimport matplotlib.pyplotas plt
url ="/tmp/databasesLoadData/sign_mnist_json/data.json"# 2data_json=[]with codecs.open(url,'rU','utf8')asjs: # 2.1for line injs: data_json.append(json.loads(line)) #deserializamos al añadir
print("{} imágenes encontradas".format(len(data_json)))# 3images =[]for data indata_json: response = requests.get(data["content"]) #secuencia de bytes
response =BytesIO(response.content) # decodifica a hexadecimal
img = np.asarray(Image.open(response)) #convierte a array
images.append([img, data["label"]])plt.imshow(images[0][0])# 4print(images[0][1])
Según la documentación el modo U (Universal Newlines) está en desuso.
Ósea que es mejor utilizar solo "r"
Buen aporte, gracias!
Despues de aplicar el ciclo for
images =[]for data in data_json: response = requests.get(data['content']) img = np.asarray(Image.open(BytesIO(response.content))) images.append([img, data["label"]])
he notado que las imagenes resultan con dimension (28,28), en ese caso ya no seria necesario redimensionar como lo hace con el reshape ???
Hola Jose, es correcto, si ya la base de datos esta en las dimensiones ideales, no es necesario re dimensionar, pero debes asegurarte que todas las imagenes cumplan con tener el mismo tamaño antes de ingresar a la primera capa de la red neuronal.
Hay otros links disponibles desde donde pueda descargar las imagenes del curso?
el codigo muestra error en esta linea
BadZipFile: File is not a zip file
También tengo el mismo problema. Es porque los datos no se descargan correctamente y nos devuelve el error ERROR 403: Forbidden.
Estoy buscando como solucionarlo.
intente con otro dataset .zip de git hub y si valio el codigo
Las imágenes en el dataset ya están 28x28 por lo que el reshape es redundante
Tuve una duda sobre por qué usar codecs a la hora de abrir el json.
import codecs
with codecs.open(url,"rU","utf-8")asjs: pass
En pocas palabras, el módulo codecs se implementó en los tiempos de Python 2 donde el modulo io.open seguía siendo relativamente primitivo y no soportaba algunos tipos de encoding, por lo que esta era una solución, sin embargo, cuando se actualizó a Python 3, el módulo io.open ya soportaba todas las características de codecs al punto que se busca activamente deprecarlo.
Lo anterior implica que usar open() y codecs.open() es virtualmente lo mismo, por lo que, a no ser que nuestro código deba ser retrocompatible, lo mejor es usar open (que es un atajo al módulo io.open).
Este código
data_json =[]with codecs.open(url,"rU","utf-8")asjs:for line injs: data_json.append(json.loads(line))print(f'{len(data_json)} imagenes encontradas')
Entonces el objeto se guarda en modo "L" (luminosity) → 1 solo canal con valores de 0 a 255 (negro a blanco).
Por eso, al convertirla con np.asarray(img), te da un array de 1 valor por pixel, no 3.
Para que al visualizar la imagen con plt.imshow() se muestre en escala de grises, es necesario agregar .convert('RGB') para generar un array de 3 canales:
Image.open(BytesIO(r.content)).convert("RGB")
Al final, pueden probar usando:
r = requests.get(data_json[0]['content'])plt.imshow(np.asarray(Image.open(BytesIO(r.content)).convert('RGB')))plt.show()
2025 Julio: Estoy trabajando todo localmente con VS Code, aqui dejo el repo con codigo actualizado por si les sirve
Si lo quieren descargar desde un JupyterNotebook en Visual studio
Hola Rubert, muchas gracias por la notificación.
Si, se desconecto el pago, pero ya volví a reactivarlo, en un par de minutos vas a poder ver nuevamente el archivo.
De nuevo gracias por notificar,
salduos
Soy nuevo en este y no me funcionan las siguintes lineas desde colab:
1 frames
/usr/lib/python3.10/zipfile.py in init(self, file, mode, compression, allowZip64, compresslevel, strict_timestamps)
1267 try:
1268 if mode == 'r':
-> 1269 self._RealGetContents()
1270 elif mode in ('w', 'x'):
1271 # set the modified flag so central directory gets written
/usr/lib/python3.10/zipfile.py in _RealGetContents(self)
1334 raise BadZipFile("File is not a zip file")
1335 if not endrec:
-> 1336 raise BadZipFile("File is not a zip file")
1337 if self.debug > 1:
1338 print(endrec)
BadZipFile: File is not a zip file
Hola Carlos Humberto,
No te preocupes que para esto estamos para resolver todas las dudas,
Podrias ir a la parte izquierda de Google Colab y confirmar que en la carpeta /tmp/ se encuentre el archivo databasesLoadData.zip, pareciera que el archivo no se encuentra y por eso te muestra ese error.
En la parte que dice "archivos",
Me cuentas, saludos
Hola una consulta, si yo tengo una tabla en google cloud platform en bigquery se podria traer al colab??
Hola Giovany,
La verdad nunca lo he hecho pero hice una pequeña busqueda y encontre buenos recursos que te permitiran hacer consultas desde Google Colab a tu tabla en Bigquery.
Configuracion
Ejemplo_practico
Me cuentas como te va, saludos
Hola profe Adonai
esta muy bueno me ayudo bastante Muchas gracias
Tengo el siguiente error al tratar de descargar la base de datos, revise bastante que no sea un error de escritura...
--2022-01-1421:55:15-- https://storage.googleapis.com/platzi-tf2/databasesLoadData.zipResolving storage.googleapis.com(storage.googleapis.com)...142.250.145.128,74.125.128.128,173.194.79.128,...Connecting to storage.googleapis.com(storage.googleapis.com)|142.250.145.128|:443...connected.HTTP request sent, awaiting response...403Forbidden2022-01-1421:55:15ERROR403:Forbidden.
el problema es que esta caida la nube de gpc donde le alojaba el zip , nunca se te descargo el zip porque esta danada la pag por lo tanto no detecta ningun archivo
no logre desacragar la base de datos, paredec un problema del servidor donde esta alojado
Para los que estan usando windows y le sale error
pip install wget!python -m wget ``
Asegúrate de que tu archivo JSON esté bien formado y no tenga errores.
Ten en cuenta la estructura de tu archivo JSON al elegir el método de carga.
Si necesitas modificar los datos de tu base de datos JSON, puedes hacerlo