• Saltar al contenido principal
  • Skip to secondary menu
  • Saltar a la barra lateral principal
  • Saltar al pie de página
  • Inicio
  • Secciones
    • Ciencia de datos
    • Criptografía
    • Herramientas
    • Machine Learning
    • Noticias
    • Opinión
    • Productividad
    • Programación
      • JavaScript
      • Julia
      • Matlab
      • Python
      • R
  • Programación
    • JavaScript
    • Julia
    • Matlab
    • Python
    • R
  • Noticias
  • Boletín
  • Contacto
  • Tienda
    • Libros
    • Equipamiento de oficina
    • Equipamiento en movilidad
    • Tiendas afiliadas
      • AliExpress
      • Amazon
      • Banggood
      • GeekBuying
      • Lenovo

Analytics Lane

Ciencia e ingeniería de datos aplicada

  • Ciencia de datos
  • Machine Learning
  • Python
  • Pandas
  • NumPy
  • Matlab
  • Julia
  • JavaScript
  • Excel

Combinar DataFrames en Julia (16ª parte – ¡Hola Julia!)

septiembre 3, 2020 Por Daniel Rodríguez Deja un comentario
Tiempo de lectura: 11 minutos

Al trabajar con diferentes conjuntos de datos puede que estos no se encuentren un único DataFrame. Por ejemplo, si lo importamos de una base de datos en el que tengamos una tabla de clientes y otra de factura. En tal caso se puede usar SQL para crear una consulta en la que unir las tablas e importar el resultado. Aunque sí queremos tener un mayor control sobre las operaciones se puede unir y combinar DataFrames en Julia con las herramientas que existen en la librería DataFrames.

Creación de un conjunto de datos

Vamos a crear un conjunto de datos similar al que usamos en su momento para explicar cómo combinar DataFrames en Python. Creando una tabla de clientes y otra tabla con algunas facturas.

using DataFrames

clients = DataFrame(
    id=[1,2,3,4,5],
    first_name=["Oralie" ,"Imojean" ,"Michele", "Ailbert", "Stevy"],
    last_name=["Fidgeon" ,"Benet" ,"Woodlands", "Risdale", "MacGorman"],
    age=[30 ,21 ,29 ,22, 24])

invoices = DataFrame(
    invoice_id=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
    client_id=[3, 2, 7, 2, 7, 3, 1, 4 ,2, 3, 6, 2],
    amount=[77.91, 24.36, 74.65, 19.75, 27.46, 17.13, 45.77, 81.7, 14.41, 52.69, 32.03, 12.78])
5×4 DataFrame
│ Row │ id    │ first_name │ last_name │ age   │
│     │ Int64 │ String     │ String    │ Int64 │
├─────┼───────┼────────────┼───────────┼───────┤
│ 1   │ 1     │ Oralie     │ Fidgeon   │ 30    │
│ 2   │ 2     │ Imojean    │ Benet     │ 21    │
│ 3   │ 3     │ Michele    │ Woodlands │ 29    │
│ 4   │ 4     │ Ailbert    │ Risdale   │ 22    │
│ 5   │ 5     │ Stevy      │ MacGorman │ 24    │

12×3 DataFrame
│ Row │ invoice_id │ client_id │ amount  │
│     │ Int64      │ Int64     │ Float64 │
├─────┼────────────┼───────────┼─────────┤
│ 1   │ 1          │ 3         │ 77.91   │
│ 2   │ 2          │ 2         │ 24.36   │
│ 3   │ 3          │ 7         │ 74.65   │
│ 4   │ 4          │ 2         │ 19.75   │
│ 5   │ 5          │ 7         │ 27.46   │
│ 6   │ 6          │ 3         │ 17.13   │
│ 7   │ 7          │ 1         │ 45.77   │
│ 8   │ 8          │ 4         │ 81.7    │
│ 9   │ 9          │ 2         │ 14.41   │
│ 10  │ 10         │ 3         │ 52.69   │
│ 11  │ 11         │ 6         │ 32.03   │
│ 12  │ 12         │ 2         │ 12.78   │

Combinación interna (INNER JOIN)

La operación más habitual a la hora de cruzar tablas es la combinación interna en la que se crea una nueva tabla únicamente con los registros relacionados de ambas. Para ello Julia cuenta con la función innerjoin() en la que se deben indicar dos DataFrames y el criterio de unión que se indica en la propiedad on. En los datos de ejemplo el identificador del cliente es id en la tabla clients, mientras que el identificador del cliente en la factura es client_id. Así para unir a los clientes con las facturas se puede hacer.

innerjoin(clients, invoices, on=:id=>:client_id)
9×6 DataFrame
│ Row │ id    │ first_name │ last_name │ age   │ invoice_id │ amount  │
│     │ Int64 │ String     │ String    │ Int64 │ Int64      │ Float64 │
├─────┼───────┼────────────┼───────────┼───────┼────────────┼─────────┤
│ 1   │ 1     │ Oralie     │ Fidgeon   │ 30    │ 7          │ 45.77   │
│ 2   │ 2     │ Imojean    │ Benet     │ 21    │ 2          │ 24.36   │
│ 3   │ 2     │ Imojean    │ Benet     │ 21    │ 4          │ 19.75   │
│ 4   │ 2     │ Imojean    │ Benet     │ 21    │ 9          │ 14.41   │
│ 5   │ 2     │ Imojean    │ Benet     │ 21    │ 12         │ 12.78   │
│ 6   │ 3     │ Michele    │ Woodlands │ 29    │ 1          │ 77.91   │
│ 7   │ 3     │ Michele    │ Woodlands │ 29    │ 6          │ 17.13   │
│ 8   │ 3     │ Michele    │ Woodlands │ 29    │ 10         │ 52.69   │
│ 9   │ 4     │ Ailbert    │ Risdale   │ 22    │ 8          │ 81.7    │

Al ser una combinación interna solamente se representan los clientes que tiene al menos una factura y las facturas que tienen un cliente en la otra tabla. Ignorando el resto de los registros. En este caso se obtienen los nueve registros de las doce facturas.

Combinaciones externas izquierda y derecha (LEFT JOIN y RIGHT JOIN)

Puede ser que necesitemos una tabla con todos los clientes, aunque estos no hayan comprado nada o todas las facturas, aunque no tengamos los datos de los clientes. En este caso la combinación interna no es válida ya que omite los casos en los que no existe relación. Por lo que es necesario usar las combinaciones externas izquierda y derecha. Las cuales se pueden implementar mediante las funciones leftjoin() o rightjoin() respectivamente. Ambas con una sintaxis similar a innerjoin().

Publicidad


En las combinaciones externas izquierdas se incluyen todos los registros del primer DataFrame (el situado a la izquierda), incluso si no existen valores coincidentes para registros en el segundo DataFrame (el situado a la izquierda). Siendo al revés en el caso de las combinaciones externas derecha. Así para obtener todos los clientes, aunque no compren nada se puede realizar mediante una combinación externa izquierda.

leftjoin(clients, invoices, on=:id=>:client_id)
10×6 DataFrame
│ Row │ id    │ first_name │ last_name │ age   │ invoice_id │ amount   │
│     │ Int64 │ String     │ String    │ Int64 │ Int64?     │ Float64? │
├─────┼───────┼────────────┼───────────┼───────┼────────────┼──────────┤
│ 1   │ 1     │ Oralie     │ Fidgeon   │ 30    │ 7          │ 45.77    │
│ 2   │ 2     │ Imojean    │ Benet     │ 21    │ 2          │ 24.36    │
│ 3   │ 2     │ Imojean    │ Benet     │ 21    │ 4          │ 19.75    │
│ 4   │ 2     │ Imojean    │ Benet     │ 21    │ 9          │ 14.41    │
│ 5   │ 2     │ Imojean    │ Benet     │ 21    │ 12         │ 12.78    │
│ 6   │ 3     │ Michele    │ Woodlands │ 29    │ 1          │ 77.91    │
│ 7   │ 3     │ Michele    │ Woodlands │ 29    │ 6          │ 17.13    │
│ 8   │ 3     │ Michele    │ Woodlands │ 29    │ 10         │ 52.69    │
│ 9   │ 4     │ Ailbert    │ Risdale   │ 22    │ 8          │ 81.7     │
│ 10  │ 5     │ Stevy      │ MacGorman │ 24    │ missing    │ missing  │

Por otro lado, una lista de todas las facturas, aunque no exista un registro con los datos del cliente se puede obtener con combinación externa derecha (o izquierda cambiando el orden de los DataFrames).

rightjoin(clients, invoices, on=:id=>:client_id)
12×6 DataFrame
│ Row │ id    │ first_name │ last_name │ age     │ invoice_id │ amount  │
│     │ Int64 │ String?    │ String?   │ Int64?  │ Int64      │ Float64 │
├─────┼───────┼────────────┼───────────┼─────────┼────────────┼─────────┤
│ 1   │ 3     │ Michele    │ Woodlands │ 29      │ 1          │ 77.91   │
│ 2   │ 2     │ Imojean    │ Benet     │ 21      │ 2          │ 24.36   │
│ 3   │ 2     │ Imojean    │ Benet     │ 21      │ 4          │ 19.75   │
│ 4   │ 3     │ Michele    │ Woodlands │ 29      │ 6          │ 17.13   │
│ 5   │ 1     │ Oralie     │ Fidgeon   │ 30      │ 7          │ 45.77   │
│ 6   │ 4     │ Ailbert    │ Risdale   │ 22      │ 8          │ 81.7    │
│ 7   │ 2     │ Imojean    │ Benet     │ 21      │ 9          │ 14.41   │
│ 8   │ 3     │ Michele    │ Woodlands │ 29      │ 10         │ 52.69   │
│ 9   │ 2     │ Imojean    │ Benet     │ 21      │ 12         │ 12.78   │
│ 10  │ 7     │ missing    │ missing   │ missing │ 3          │ 74.65   │
│ 11  │ 7     │ missing    │ missing   │ missing │ 5          │ 27.46   │
│ 12  │ 6     │ missing    │ missing   │ missing │ 11         │ 32.03   │

Nótese que en estos casos los registros que faltan son reemplazados por missing. Cambiando el tipo de dato de la columna del original a una unión de con el tipo Missing. Lo que se denota por el signo de interrogación al final del tipo de dato.

Combinaciones externas (OUTER JOIN)

outerjoin(clients, invoices, on=:id=>:client_id)
13×6 DataFrame
│ Row │ id    │ first_name │ last_name │ age     │ invoice_id │ amount   │
│     │ Int64 │ String?    │ String?   │ Int64?  │ Int64?     │ Float64? │
├─────┼───────┼────────────┼───────────┼─────────┼────────────┼──────────┤
│ 1   │ 1     │ Oralie     │ Fidgeon   │ 30      │ 7          │ 45.77    │
│ 2   │ 2     │ Imojean    │ Benet     │ 21      │ 2          │ 24.36    │
│ 3   │ 2     │ Imojean    │ Benet     │ 21      │ 4          │ 19.75    │
│ 4   │ 2     │ Imojean    │ Benet     │ 21      │ 9          │ 14.41    │
│ 5   │ 2     │ Imojean    │ Benet     │ 21      │ 12         │ 12.78    │
│ 6   │ 3     │ Michele    │ Woodlands │ 29      │ 1          │ 77.91    │
│ 7   │ 3     │ Michele    │ Woodlands │ 29      │ 6          │ 17.13    │
│ 8   │ 3     │ Michele    │ Woodlands │ 29      │ 10         │ 52.69    │
│ 9   │ 4     │ Ailbert    │ Risdale   │ 22      │ 8          │ 81.7     │
│ 10  │ 5     │ Stevy      │ MacGorman │ 24      │ missing    │ missing  │
│ 11  │ 7     │ missing    │ missing   │ missing │ 3          │ 74.65    │
│ 12  │ 7     │ missing    │ missing   │ missing │ 5          │ 27.46    │
│ 13  │ 6     │ missing    │ missing   │ missing │ 11         │ 32.03    │

Otra opción a la hora de combinar dos DataFrames es realizar una unión externa en la que se recogerán todos los registros de las dos tablas, aunque no exista relación con uno de la otra. Algo que se puede realizar mediante el uso de la función outerjoin().

Semicombinaciones

Hasta ahora el resultado de las funciones es un nuevo DataFrame con los datos de los combinar los dos anteriores. Pero puede que no sean necesarios los datos de una de las dos tablas. Ya que podemos querer solamente los clientes que han comprado y los que no. Esto se puede hacer con la función semijoin(), en los que el resultado serán los registros del primer DataFrame que estén relacionados con el segundo. La forma de llamar la función es exactamente igual a las funciones vistas anteriormente.

Publicidad


semijoin(clients, invoices, on=:id=>:client_id)
4×4 DataFrame
│ Row │ id    │ first_name │ last_name │ age   │
│     │ Int64 │ String     │ String    │ Int64 │
├─────┼───────┼────────────┼───────────┼───────┤
│ 1   │ 1     │ Oralie     │ Fidgeon   │ 30    │
│ 2   │ 2     │ Imojean    │ Benet     │ 21    │
│ 3   │ 3     │ Michele    │ Woodlands │ 29    │
│ 4   │ 4     │ Ailbert    │ Risdale   │ 22    │

Alternativamente se pueden obtener la lista de registros del primer DataFrame que no tiene relación mediante antijoin().

antijoin(clients, invoices, on=:id=>:client_id)
1×4 DataFrame
│ Row │ id    │ first_name │ last_name │ age   │
│     │ Int64 │ String     │ String    │ Int64 │
├─────┼───────┼────────────┼───────────┼───────┤
│ 1   │ 5     │ Stevy      │ MacGorman │ 24    │

Combinar con múltiples criterios

Ahora nos puede surgir un problema, ¿qué pasa si tenemos más de un criterio para la combinación de los datos de dos DataFrames? Por ejemplo, tenemos varias tiendas y en cada una de ellas el cliente tiene un identificador diferente. En este caso solo hay que pasar en un vector los criterios de unión. Así se puede crear un nuevo ejemplo en que se añade un identificador de tiene tanto al cliente como a la factura. Por lo que lo que hace único un registro es la combinación de ambos.

clients = DataFrame(store_id=[1, 1, 1, 2, 2, 2],
    client_id=[1, 2, 3, 1, 2, 3],
    first_name=["Oralie" ,"Imojean" ,"Michele", "Ailbert", "Stevy", "Imojean"],
    last_name=["Fidgeon" ,"Benet" ,"Woodlands", "Risdale", "MacGorman", "Benet"],
    age=[30 ,21 ,29 ,22, 24, 22])

invoices = DataFrame(invoice_id=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
    store_id=[1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
    client_id=[3, 2, 7, 2, 7, 3, 1, 4 ,2, 3, 6, 2],
    amount=[77.91, 24.36, 74.65, 19.75, 27.46, 17.13, 45.77, 81.7, 14.41, 52.69, 32.03, 12.78])
6×5 DataFrame
│ Row │ store_id │ client_id │ first_name │ last_name │ age   │
│     │ Int64    │ Int64     │ String     │ String    │ Int64 │
├─────┼──────────┼───────────┼────────────┼───────────┼───────┤
│ 1   │ 1        │ 1         │ Oralie     │ Fidgeon   │ 30    │
│ 2   │ 1        │ 2         │ Imojean    │ Benet     │ 21    │
│ 3   │ 1        │ 3         │ Michele    │ Woodlands │ 29    │
│ 4   │ 2        │ 1         │ Ailbert    │ Risdale   │ 22    │
│ 5   │ 2        │ 2         │ Stevy      │ MacGorman │ 24    │
│ 6   │ 2        │ 3         │ Imojean    │ Benet     │ 22    │

12×4 DataFrame
│ Row │ invoice_id │ store_id │ client_id │ amount  │
│     │ Int64      │ Int64    │ Int64     │ Float64 │
├─────┼────────────┼──────────┼───────────┼─────────┤
│ 1   │ 1          │ 1        │ 3         │ 77.91   │
│ 2   │ 2          │ 1        │ 2         │ 24.36   │
│ 3   │ 3          │ 1        │ 7         │ 74.65   │
│ 4   │ 4          │ 1        │ 2         │ 19.75   │
│ 5   │ 5          │ 1        │ 7         │ 27.46   │
│ 6   │ 6          │ 1        │ 3         │ 17.13   │
│ 7   │ 7          │ 2        │ 1         │ 45.77   │
│ 8   │ 8          │ 2        │ 4         │ 81.7    │
│ 9   │ 9          │ 2        │ 2         │ 14.41   │
│ 10  │ 10         │ 2        │ 3         │ 52.69   │
│ 11  │ 11         │ 2        │ 6         │ 32.03   │
│ 12  │ 12         │ 2        │ 2         │ 12.78   │

Así para obtener una combinación interna de ambas solo tenemos que modificar el criterio como se muestra a continuación.

innerjoin(clients, invoices, on=[:client_id, :store_id])
8×7 DataFrame
│ Row │ store_id │ client_id │ first_name │ last_name │ age   │ invoice_id │ amount  │
│     │ Int64    │ Int64     │ String     │ String    │ Int64 │ Int64      │ Float64 │
├─────┼──────────┼───────────┼────────────┼───────────┼───────┼────────────┼─────────┤
│ 1   │ 1        │ 2         │ Imojean    │ Benet     │ 21    │ 2          │ 24.36   │
│ 2   │ 1        │ 2         │ Imojean    │ Benet     │ 21    │ 4          │ 19.75   │
│ 3   │ 1        │ 3         │ Michele    │ Woodlands │ 29    │ 1          │ 77.91   │
│ 4   │ 1        │ 3         │ Michele    │ Woodlands │ 29    │ 6          │ 17.13   │
│ 5   │ 2        │ 1         │ Ailbert    │ Risdale   │ 22    │ 7          │ 45.77   │
│ 6   │ 2        │ 2         │ Stevy      │ MacGorman │ 24    │ 9          │ 14.41   │
│ 7   │ 2        │ 2         │ Stevy      │ MacGorman │ 24    │ 12         │ 12.78   │
│ 8   │ 2        │ 3         │ Imojean    │ Benet     │ 22    │ 10         │ 52.69   │

Combinar DataFrames en Julia con la potencia de SQL

Las posibilidades a la hora de combinar DataFrames en Julia son similares a las que nos puede ofrecer SQL. Lo que nos permite importar los datos directamente y realizar las combinaciones directamente en la sesión de Julia. Por lo que, sí necesitamos al estar trabajando vemos que necesitas otro tipo de combinación solo se puede realizar rápidamente sin tener que volver a la base de datos.

Publicaciones de la serie ¡Hola Julia!

  1. ¡Hola Julia!
  2. Primeros pasos con Julia
  3. Cadenas de texto en Julia
  4. Bucles en Julia
  5. Funciones en Julia
  6. Vectores, tuplas y diccionarios en Julia
  7. Estructuras en Julia
  8. Utilizar los tipos en Julia
  9. Tipos de datos en Julia
  10. Tipos y funciones paramétricos en Julia
  11. Introducción a los DataFrames en Julia
  12. Obtener información básica de los DataFrames de Julia
  13. El tipo de dato Missing de Julia
  14. Columnas en DataFrames de Julia
  15. Filas en DataFrames de Julia
  16. Combinar DataFrames en Julia
  17. Guardar y leer archivos CSV en Julia
  18. Guardar y leer archivos Excel en Julia
  19. Introducción a Genie
  20. Libros sobre Julia

¿Te ha parecido de utilidad el contenido?

¡Puntúalo entre una y cinco estrellas!

Puntuación promedio 5 / 5. Votos emitidos: 1

Publicidad


Ya que has encontrado útil este contenido...

¡Síguenos en redes sociales!

¡Siento que este contenido no te haya sido útil!

¡Déjame mejorar este contenido!

Dime, ¿cómo puedo mejorar este contenido?

Publicaciones relacionadas

  • Guardar y leer archivos CSV en Julia (17ª parte – ¡Hola Julia!)
    Guardar y leer archivos CSV en Julia (17ª parte – ¡Hola…
  • Filas en DataFrames de Julia (15ª parte – ¡Hola Julia!)
    Filas en DataFrames de Julia (15ª parte – ¡Hola Julia!)
  • Cadenas de texto en Julia (3ª parte - ¡Hola Julia!)
    Cadenas de texto en Julia (3ª parte - ¡Hola Julia!)
  • Tipos y funciones paramétricos en Julia (10ª parte – ¡Hola Julia!)
    Tipos y funciones paramétricos en Julia (10ª parte – ¡Hola…
  • ¡Hola Julia!
    ¡Hola Julia!
  • Primeros pasos con Julia (2ª parte - ¡Hola Julia!)
    Primeros pasos con Julia (2ª parte - ¡Hola Julia!)

Publicado en: Julia

Interacciones con los lectores

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

I accept the Terms and Conditions and the Privacy Policy

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Publicidad




Barra lateral principal

Suscríbete a nuestro boletín

Suscríbete al boletín semanal para estar al día de todas las publicaciones.

Política de Privacidad

Analytics Lane en redes sociales

  • Amazon
  • Facebook
  • GitHub
  • Instagram
  • Pinterest
  • RSS
  • Twitter
  • Tumblr
  • YouTube

Publicidad

Entradas recientes

El método de Hare-Niemeyer y su implementación en Python

septiembre 29, 2023 Por Daniel Rodríguez

Redimensionar una partición de disco LVM con espacio no asignado en Linux

septiembre 27, 2023 Por Daniel Rodríguez

¿Cómo saber la versión de Pandas o cualquier otra librería en Python?

septiembre 25, 2023 Por Daniel Rodríguez

Publicidad

Es tendencia

  • ¿Cómo cambiar el nombre de las columnas en Pandas? publicado el mayo 6, 2019 | en Python
  • Seleccionar filas y columnas en Pandas con iloc y loc publicado el junio 21, 2019 | en Python
  • pandas Pandas: Cambiar los tipos de datos en los DataFrames publicado el julio 15, 2021 | en Python
  • Numpy básico: valores mínimos y máximos en arrays Numpy publicado el octubre 23, 2019 | en Python
  • Unir y combinar dataframes con pandas en Python publicado el septiembre 10, 2018 | en Python

Publicidad

Lo mejor valorado

4.9 (22)

Seleccionar filas y columnas en Pandas con iloc y loc

4.7 (12)

Operaciones de filtrado de DataFrame con Pandas en base a los valores de las columnas

4.6 (15)

Archivos JSON con Python: lectura y escritura

4.5 (10)

Diferencias entre var y let en JavaScript

4.3 (12)

Ordenación de diccionarios en Python mediante clave o valor

Publicidad

Comentarios recientes

  • Daniel Rodríguez en ¿Cómo eliminar columnas y filas en un dataframe pandas?
  • Miguel en ¿Cómo eliminar columnas y filas en un dataframe pandas?
  • alberto en Resolver problema de credenciales en Bitbucket
  • Pablo en Aplicar el método D’Hondt en Excel
  • Agapito en Creación de un EXE desde un archivo Python en Windows

Publicidad

Footer

Analytics Lane

  • Acerca de Analytics Lane
  • Boletín de noticias
  • Contacto
  • Libros
  • Lo más popular
  • Noticias
  • Tienda
  • Tiendas afiliadas

Secciones

  • Ciencia de datos
  • Criptografía
  • Herramientas
  • Machine Learning
  • Opinión
  • Productividad
  • Programación
  • Reseñas

Sobre de Analytics Lane

En Analytics Lane tratamos de explicar los principales conceptos de la ciencia e ingeniería de datos con un enfoque práctico. Los principales temas tratados son ciencia de datos, ingeniería de datos, inteligencia artificial, machine learning, deep learning y criptografía. Además, también se habla de los principales lenguajes de programación y herramientas utilizadas por los científicos e ingenieros de datos.

Copyright © 2018-2023 Analytics Lane ·Términos y condiciones ·Política de Cookies ·Política de Privacidad ·Herramientas de privacidad ·Contacto