python - index - pandas dataframe tutorial
Lista con muchos diccionarios VS diccionario con pocas listas? (6)
Estoy haciendo algunos ejercicios con conjuntos de datos así:
Lista con muchos diccionarios
users = [
{"id": 0, "name": "Ashley"},
{"id": 1, "name": "Ben"},
{"id": 2, "name": "Conrad"},
{"id": 3, "name": "Doug"},
{"id": 4, "name": "Evin"},
{"id": 5, "name": "Florian"},
{"id": 6, "name": "Gerald"}
]
Diccionario con pocas listas
users2 = {
"id": [0, 1, 2, 3, 4, 5, 6],
"name": ["Ashley", "Ben", "Conrad", "Doug","Evin", "Florian", "Gerald"]
}
Marcos de datos de pandas
import pandas as pd
pd_users = pd.DataFrame(users)
pd_users2 = pd.DataFrame(users2)
print pd_users == pd_users2
Preguntas:
- ¿Debo estructurar los conjuntos de datos como usuarios o como usuarios2?
- ¿Hay diferencias de rendimiento?
- ¿Es uno más legible que el otro?
- ¿Hay alguna norma que deba seguir?
- Normalmente los convierto a marcos de datos pandas. Cuando hago eso, ambas versiones son idénticas ... ¿verdad?
- La salida es verdadera para cada elemento, por lo que no importa si trabajo con panda df, ¿verdad?
Algunas respuestas sobre el aspecto de los pandas:
- Ambos marcos de datos son de hecho iguales y están orientados a la columna, lo que es bueno, porque los pandas funcionan mejor cuando los datos en cada columna son homogéneos (es decir, los números se pueden almacenar como ints y flotadores). Una razón clave para usar pandas en primer lugar es que puede realizar operaciones numéricas vectorizadas que son órdenes de magnitud más rápidas que Python puro, pero esto se basa en la organización de columnas cuando los datos son de tipo heterogéneo.
- Podría hacer
pd_users.T
para transponer, si quisiera, y luego vería (a través deinfo()
odtypes
) que todo se almacena como un objeto de propósito general porque la columna contiene cadenas y números. - Una vez convertido, puede hacer
pd_users.set_index(''id'')
para que su marco de datos sea esencialmente un diccionario conid
como las claves. O viceversa conname
. - Es bastante común (y generalmente bastante rápido) cambiar los índices, luego volverlos a cambiar, transponer, subconjuntar, etc. cuando se trabaja con pandas, por lo que generalmente no es necesario pensar demasiado sobre la estructura al principio. Solo cámbiala como necesites sobre la marcha.
- Esto puede estar saliendo en una tangente, pero un análogo de pandas más simple de lo que tienes arriba puede ser una
Series
lugar de unDataFrame
deDataFrame
. Una serie es esencialmente una columna de un marco de datos, aunque en realidad es solo una matriz de datos unidimensional con un índice ("claves").
Demostración rápida (usando df
como el nombre del marco de datos, la convención común):
>>> df.set_index(''name'')
id
name
Ashley 0
Ben 1
Conrad 2
Doug 3
Evin 4
Florian 5
Gerald 6
>>> df.set_index(''name'').T
name Ashley Ben Conrad Doug Evin Florian Gerald
id 0 1 2 3 4 5 6
>>> df.set_index(''name'').loc[''Doug'']
id 3
Name: Doug, dtype: int64
Esto se relaciona con las bases de datos orientadas a columnas versus orientadas a filas. Su primer ejemplo es una estructura de datos orientada a filas, y el segundo está orientado a columnas. En el caso particular de Python, el primero se podría hacer notablemente más eficiente utilizando slots , de modo que el diccionario de columnas no necesita ser duplicado para cada fila.
Qué forma funciona mejor depende mucho de lo que haga con los datos; por ejemplo, la fila orientada es natural si solo accedes a todas las filas. Mientras tanto, la columna orientada hace un uso mucho mejor de los cachés y, por lo tanto, cuando se busca por un campo en particular (en Python, esto puede reducirse por el uso intensivo de referencias; los tipos como array pueden optimizar eso). Las bases de datos orientadas a filas tradicionales con frecuencia utilizan índices ordenados orientados a columnas para acelerar las búsquedas y, al conocer estas técnicas, puede implementar cualquier combinación utilizando un almacén de valores clave.
Pandas convierte ambos ejemplos al mismo formato, pero la conversión en sí misma es más cara para la estructura orientada a filas, simplemente porque se debe leer cada diccionario individual. Todos estos costos pueden ser marginales.
Hay una tercera opción que no es evidente en su ejemplo: en este caso, solo tiene dos columnas, una de las cuales es un ID entero en un rango contiguo desde 0. Esto se puede almacenar en el orden de las entradas, lo que significa toda la estructura se encontraría en la lista que has llamado users2[''name'']
; pero notablemente, las entradas están incompletas sin su posición. La lista se traduce en filas usando enumerate (). Es común que las bases de datos tengan este caso especial también (por ejemplo, sqlite rowid ).
En general, comience con una estructura de datos que mantenga su código sensible y optimice solo cuando conozca sus casos de uso y tenga un problema de rendimiento medible. Las herramientas como Pandas probablemente significan que la mayoría de los proyectos funcionarán bien sin necesidad de ajuste.
La complejidad del tiempo para las búsquedas en -
- Lista - O (n)
- Dictados - O (1)
Pero eso no perjudicaría mucho si sus datos no son tan grandes y también los procesadores modernos son bastante eficientes.
Debe ir con aquel en el que la búsqueda sea sintácticamente más limpia y legible (la legibilidad es importante).
La primera opción es bastante apropiada ya que la variable es una colección de usuarios (a los que se les ha asignado una identificación), mientras que la segunda sería solo una colección de nombres de usuario e identificaciones.
La primera opción de la lista de diccionarios será mucho mejor por varias razones. La lista sí proporciona métodos tales como EXTEND, APPENT, PUSH que no están fácilmente disponibles con los diccionarios.
users
en sentido general es en realidad una colección de elementos de user
. Por lo tanto, es mejor definir el elemento de user
como una entidad independiente. Así que tu primera opción es la correcta.
Usuarios
Cuando necesite agregar un nuevo usuario, simplemente haga un nuevo
dict
de todos los detalles del usuario y agrégueloFácil de ordenar como sugirió @StevenRumbalski
La búsqueda será fácil
Esto es más compacto y fácil de manejar a medida que crece el registro (para un número muy alto de registros, creo que también necesitaremos algo mejor que los usuarios)
Usuarios2
- Personalmente estoy viendo esto por primera vez y no me acercaría a esto si tuviera un gran número de registros.
PD: Pero me gustaría conocer las ventajas de users2
sobre los users
Otra vez, una buena pregunta.