es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe una forma más rápida de crear un DataFrame de Pandas a partir de un arreglo nd de Numpy con descripciones?

Me gustaría transformar una matriz numpy nd con descripciones de dimensiones en un dataframe de pandas.
Las siguientes soluciones funcionan, pero parecen un poco lentas para 360000 filas (1.5s en mi máquina, sus resultados pueden variar).

import pandas as pd
import numpy as np
from itertools import product
import time

preparación de los datos

nd_data = np.random.random((5, 3, 100, 10, 4, 6))
dimension_descriptions = {
    'floaty': [0.1,0.2,0.3,0.4,0.5],
    'animal': ['patos', 'caballos', 'elefantes'],
    'rampa': range(100),
    'otra_rampa': range(10),
    'número interesante': [12, 15, 29, 42],
    'porque': ['por qué', 'es', 'seis', 'temeroso', 'de', 'siete']
}

t_start = time.time()

crear un dataframe a partir de una lista de diccionarios que contienen datos y descripciones permutadas

df = pd.DataFrame([{'data': data, **dict(zip(dimension_descriptions.keys(), permuted_description))}
                   for data, permuted_description in zip(nd_data.flatten(), product(*dimension_descriptions.values()))])
print(f'tiempo transcurrido: {time.time()- t_start:.1f}s')

¿Hay una forma más rápida de lograr el mismo resultado?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma más rápida de lograr el mismo resultado. En lugar de crear una lista de diccionarios y luego crear un DataFrame a partir de ella, podemos utilizar la función reshape de NumPy para transformar la matriz nd en una matriz 2D y luego crear directamente un DataFrame a partir de ella. Aquí está el código modificado:

    import pandas as pd
    import numpy as np
    from itertools import product
    import time
    
    # preparación de los datos
    nd_data = np.random.random((5, 3, 100, 10, 4, 6))
    dimension_descriptions = {
        'floaty': [0.1,0.2,0.3,0.4,0.5],
        'animal': ['ducks', 'horses', 'elephants'],
        'ramp': range(100),
        'another_ramp': range(10),
        'interesting number': [12, 15, 29, 42],
        'because': ['why', 'is', 'six', 'afraid', 'of', 'seven']
    }
    
    t_start = time.time()
    # convertir la matriz nd en una matriz 2D
    nd_data_2d = np.reshape(nd_data, (-1, nd_data.shape[-2]*nd_data.shape[-1]))
    
    # crear MultiIndex a partir de las descripciones de las dimensiones
    ix = pd.MultiIndex.from_product(dimension_descriptions.values(), names=dimension_descriptions.keys())
    
    # crear DataFrame a partir de la matriz 2D y el MultiIndex
    df = pd.DataFrame(nd_data_2d, index=ix).T
    
    print(f'tiempo transcurrido: {time.time()- t_start:.1f}s')
    

    Esto debería ser significativamente más rápido que el enfoque original para matrices grandes. Note que también creamos un MultiIndex a partir de las descripciones de las dimensiones para preservar las dimensiones originales de la matriz en el DataFrame.

Comments are closed.