Columnas duplicadas en Julia Dataframes

Aug 25 2020

En Python Pandas y R, uno puede deshacerse de las columnas duplicadas fácilmente: solo cargue los datos, asigne los nombres de las columnas y seleccione las que no están duplicadas.

¿Cuáles son las mejores prácticas para tratar estos datos con Julia Dataframes? Aquí no se permite asignar nombres de columna duplicados. Entiendo que la única forma sería masajear más los datos entrantes y deshacerse de esos datos antes de construir un marco de datos.

El problema es que casi siempre es más fácil lidiar con columnas duplicadas en el marco de datos que ya está construido, en lugar de los datos entrantes.

UPD: Me refiero a los nombres de columna duplicados. Construyo un marco de datos a partir de datos sin procesar, donde los nombres de las columnas (y, por lo tanto, los datos) podrían repetirse.

UPD2: Se agregó un ejemplo de Python.

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame(np.hstack([np.zeros((4,1)), np.ones((4,2))]), columns=["a", "b", "b"])
>>> df
     a    b    b
0  0.0  1.0  1.0
1  0.0  1.0  1.0
2  0.0  1.0  1.0
3  0.0  1.0  1.0
>>> df.loc[:, ~df.columns.duplicated()]
     a    b
0  0.0  1.0
1  0.0  1.0
2  0.0  1.0
3  0.0  1.0

Construyo mi Julia Dataframe a partir de una matriz Float32 y luego asigno nombres de columna desde un vector. Ahí es donde necesito deshacerme de las columnas que tienen nombres duplicados (ya presentes en el marco de datos). Esa es la naturaleza de los datos subyacentes, a veces tiene dups, a veces no, no tengo control sobre su creación.

Respuestas

2 BogumiłKamiński Aug 24 2020 at 23:38

¿Es esto algo que está buscando (no estaba 100% seguro de su descripción; si esto no es lo que desea, actualice la pregunta con un ejemplo):

julia> df = DataFrame([zeros(4,3) ones(4,5)])
4×8 DataFrame
│ Row │ x1      │ x2      │ x3      │ x4      │ x5      │ x6      │ x7      │ x8      │
│     │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │
├─────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ 1   │ 0.0     │ 0.0     │ 0.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │
│ 2   │ 0.0     │ 0.0     │ 0.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │
│ 3   │ 0.0     │ 0.0     │ 0.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │
│ 4   │ 0.0     │ 0.0     │ 0.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │ 1.0     │

julia> DataFrame(unique(last, pairs(eachcol(df))))
4×2 DataFrame
│ Row │ x1      │ x4      │
│     │ Float64 │ Float64 │
├─────┼─────────┼─────────┤
│ 1   │ 0.0     │ 1.0     │
│ 2   │ 0.0     │ 1.0     │
│ 3   │ 0.0     │ 1.0     │
│ 4   │ 0.0     │ 1.0     │

EDITAR

Para deduplicar nombres de columnas, use el makeuniqueargumento de palabra clave:

julia> DataFrame(rand(3,4), [:x, :x, :x, :x], makeunique=true)
3×4 DataFrame
│ Row │ x         │ x_1      │ x_2      │ x_3       │
│     │ Float64   │ Float64  │ Float64  │ Float64   │
├─────┼───────────┼──────────┼──────────┼───────────┤
│ 1   │ 0.410494  │ 0.775563 │ 0.819916 │ 0.0520466 │
│ 2   │ 0.0503997 │ 0.427499 │ 0.262234 │ 0.965793  │
│ 3   │ 0.838595  │ 0.996305 │ 0.833607 │ 0.953539  │

EDITAR 2

Entonces, parece que tiene acceso a los nombres de las columnas al crear un marco de datos. En este caso haría:

julia> mat = [ones(3,1) zeros(3,2)]
3×3 Array{Float64,2}:
 1.0  0.0  0.0
 1.0  0.0  0.0
 1.0  0.0  0.0

julia> cols = ["a", "b", "b"]
3-element Array{String,1}:
 "a"
 "b"
 "b"

julia> df = DataFrame(mat, cols, makeunique=true)
3×3 DataFrame
│ Row │ a       │ b       │ b_1     │
│     │ Float64 │ Float64 │ Float64 │
├─────┼─────────┼─────────┼─────────┤
│ 1   │ 1.0     │ 0.0     │ 0.0     │
│ 2   │ 1.0     │ 0.0     │ 0.0     │
│ 3   │ 1.0     │ 0.0     │ 0.0     │

julia> select!(df, unique(cols))
3×2 DataFrame
│ Row │ a       │ b       │
│     │ Float64 │ Float64 │
├─────┼─────────┼─────────┤
│ 1   │ 1.0     │ 0.0     │
│ 2   │ 1.0     │ 0.0     │
│ 3   │ 1.0     │ 0.0     │