¿Eliminar filas duplicadas de forma selectiva?

Un usuario Pregunto ✅

Anónimo

En el editor de consultas, hay una función que permite a un desarrollador eliminar filas duplicadas en función de las columnas seleccionadas.

Quiero agregar una condición adicional a esto. Es decir, quiero elegir qué fila eliminar en función del valor en columnas no relacionadas.

Por ejemplo, en la siguiente tabla, suponga que quiero eliminar los duplicados según las columnas «ID» y «Fecha». Sin embargo, quiero priorizar la eliminación de filas donde ID = B. No quiero que la eliminación sea arbitraria.

IDENTIFICACIÓN Escribe Fecha
1 B 1/1/2018
1 A 1/1/2018
2 A 1/1/2018
3 A 1/1/2018
4 A 1/1/2018
4 A 1/1/2018
5 A 1/1/2018
5 B 1/1/2018

Función M «Tabla.Distinta» –

Table.Distinct(table as table, optional equationCriteria as any)

Parece que debería poder incluirlo en los «criterios de ecuación opcionales», pero solo estoy adivinando y me quedo corto. ¿Algún tipo de declaración if…?

jthomson

Power Query, si estoy leyendo mi propio pbix justo donde tengo una situación similar (he agregado un nuevo informe a uno anterior y si hay un número de caso coincidente, quiero conservar los datos del nuevo informe), elimina los duplicados de abajo hacia arriba: si crea una columna personalizada que le da a cualquier cosa que sea de tipo A el valor 1 y escriba B el valor 2, luego ordene ascendentemente en la nueva columna, esto debería obligarlo a eliminar las filas que desea

jthomson

Power Query, si estoy leyendo mi propio pbix justo donde tengo una situación similar (he agregado un nuevo informe a uno anterior y si hay un número de caso coincidente, quiero conservar los datos del nuevo informe), elimina los duplicados de abajo hacia arriba: si crea una columna personalizada que le da a cualquier cosa que sea de tipo A el valor 1 y escriba B el valor 2, luego ordene ascendentemente en la nueva columna, esto debería obligarlo a eliminar las filas que desea

Anónimo

En respuesta a jthomson

Solución interesante. Eso debería funcionar…

Otra pregunta: ¿hay alguna forma de ver las filas que se eliminan? Mi conjunto de datos es de casi un millón de filas. Aplicar algo como esto sin ver directamente lo que se cambió es un dolor.

En respuesta a Anónimo

Hola @Anonimo,

Después de investigar y probar, hay una manera de ver las filas movidas usando la declaración de consulta.

Crea una tabla de copia de su tabla de recursos, elimina las filas duplicadas en su tabla original. Luego combine la tabla original (ha eliminado las filas duplicadas) en la tabla de copia usando la unión interna. Luego puede filtrar la tabla combinada para obtener todas las filas eliminadas.

Por ejemplo, mi tabla de muestra se llama ‘Table1’, creo una tabla de copia ‘Copy_Table1’. Eliminar las filas duplicadas en Table1 según [Area], luego combínalo con Copy_Table1. Filtrar Copy_Table1 basado en [Copy_Table1.Record Number]=[Table1.Record Number], eventualmente elimine las columnas innecesarias, obtendrá el resultado esperado. La siguiente es mi declaración.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("jdO7EoJADIXhV2G2piBZdoFSe8dCO4bCC63MqBS+vZBjg01OkSKTr/snfR8klOE0P+6XT1kcb+/pOj4LSWWhlTTLabeMaBjKPigho8lIyNpkTchkMhEym8yEbEyu62H6k3krW5MtITuTnS+1MikVQQV0rXSex9fWNluLTKKMRSiJjEUqcVrtV4pW4sQyilji1DKKWrZ7FLmkJSh6SefTiGDqBDOKYCoE/b2VEhS5NBIUtbR2yppFLk2MRS/NjF2CDV8=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Record Number" = _t, #"Starting Date" = _t, Area = _t, Count = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Record Number", Int64.Type}, {"Starting Date", type date}, {"Area", type text}, {"Count", Int64.Type}}),
    #"Merged Queries" = Table.NestedJoin(#"Changed Type",{"Area"},Table1,{"Area"},"Table1",JoinKind.Inner),
    #"Expanded Table1" = Table.ExpandTableColumn(#"Merged Queries", "Table1", {"Record Number", "Starting Date", "Area", "Count"}, {"Table1.Record Number", "Table1.Starting Date", "Table1.Area", "Table1.Count"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Table1", "Custom", each if [Record Number]=[Table1.Record Number] then"Yes" else "No"),
    #"Filtered Rows" = Table.SelectRows(#"Added Custom", each [Custom] = "No"),
    #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"Table1.Record Number", "Table1.Starting Date", "Table1.Area", "Table1.Count", "Custom"})
in
    #"Removed Columns"

Puede descargar el archivo .pbix para obtener más detalles.

Atentamente,
ángelia

Anónimo

En respuesta a v-huizhn-msft

Gracias @v-huizhn-msft

Creo que encontré una solución un poco más simple.

Tomé la tabla original (con la clasificación aplicada) y la dupliqué como sugirió. En la nueva tabla eliminé los duplicados. Luego me fusioné usando Anti Join en lugar de Inner Join.

Anti Join devuelve todas las filas de una tabla que no se encuentran en la otra tabla. Ahorró algunos pasos con este método.

Marcel Beug

En respuesta a v-huizhn-msft

Tenga en cuenta 1 fenómeno importante (o error, si lo desea) al ordenar primero una tabla y luego eliminar los duplicados: debe almacenar la tabla en un búfer después de la clasificación, antes de eliminar los duplicados; de lo contrario, los registros pueden eliminarse sin tener en cuenta el orden de clasificación.

Ordenado = Tabla.Ordenar(Código de clasificacion)

Buffered = Table.Buffer(Ordenado)

RemovedDuplicates = Table.Distinct(Buffered, criterios de ecuación)

o:

Ordenado = Tabla.Buffer(Table.Sort(código de clasificación))

RemovedDuplicates = Table.Distinct(Ordenado, criterios de ecuación)

El parámetro ecuaciónCritera puede incluir nombres de campo y/o funciones de comparación.

Con las funciones de comparación, puede ignorar el caso y/o usar un código cultural: por ejemplo, «æ» y «ae» se consideran iguales en algunas culturas.

El parámetro puede adoptar varios formatos, como se ilustra en los ejemplos a continuación.

let
    Source = #table(type table[Text1 = text, Text2 = text],{{"a", "Encyclopaedia"},{"A","Encyclopædia"}}),

// ****   Format equationCriteria: comparer function
    // Result: both records ("a" and "A" are not equal):
    RemovedDuplicates1 = Table.Distinct(Source, Comparer.FromCulture("en-US")),

    // Result: 1 record (æ and ae are considered equal in "en-US"; true = ignore case))
    RemovedDuplicates2 = Table.Distinct(Source, Comparer.FromCulture("en-US", true)),

    // Result: 2 records (æ and ae are not considered equal in "da-DK")
    RemovedDuplicates3 = Table.Distinct(Source, Comparer.FromCulture("da-DK", true)),

    Indexed = Table.AddIndexColumn(RemovedDuplicates2, "Index", 0, 1),

// ****   Format equationCriteria: (list of) field name(s) (as generated from the user interface if columns were selected):
    RemovedDuplicates4 = Table.Distinct(Indexed, "Text1"),
    RemovedDuplicates5 = Table.Distinct(Indexed, {"Text1"}),
    RemovedDuplicates6 = Table.Distinct(Indexed, {"Text1","Text2"}),

// ****   Format equationCriteria: list of field name with comparer function:
    RemovedDuplicates7 = Table.Distinct(Indexed, {"Text1", Comparer.OrdinalIgnoreCase}),

// ****   Format equationCriteria: list of lists with field name and comparer function:
    RemovedDuplicates8 = Table.Distinct(Indexed, {{"Text1", Comparer.OrdinalIgnoreCase},{"Text2",Comparer.FromCulture("en-US")}})

in
    RemovedDuplicates8

Anónimo

En respuesta a Marcel Beug

El Table.Buffer fue un salvavidas. Pensé en ordenar y luego eliminar los duplicados, pero durante mucho tiempo parecía que no funcionaba.

Anónimo

En respuesta a Marcel Beug

Gracias @MarcelBeug por compartir conocimientos. Incluiré el paso para almacenar en búfer la tabla antes de eliminar los duplicados.

Prestigio.

edhans

En respuesta a Anónimo

En mi humilde opinión, el anti-join es el camino a seguir aquí. Nunca me gusta clasificar y confiar en alguna lógica no documentada para que siempre funcione o no cambie en el futuro.

Deja un comentario

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