¿Cómo encontrar un conjunto de columnas para un candidato de clave principal en un archivo CSV?

Tengo un archivo CSV (no normalizado, ejemplo, archivo real de hasta 100 columnas):

ID, CUST_NAME, CLIENT_NAME, PAYMENT_NUM, START_DATE, END_DATE 1, CUST1, CLIENT1, 10, 2018-04-01, 2018-04-02 2, CUST1, CLIENT1, 10, 2018-04-01, 2018-05-30 3, CUST1, CLIENT1, 101, 2018-04-02, 2018-04-03 4, CUST2, CLIENT1, 102, 2018-04-02, 2018-04-03 

¿Cómo puedo encontrar TODOS los conjuntos de columnas posibles que podrían usarse como clave principal?

Salida deseada:

  1) ID 2) PAYMENT_NUM,START_DATE,END_DATE 3) CUST_NAME, CLIENT_NAME, PAYMENT_NUM,START_DATE,END_DATE 

Podría hacerlo en Java, pero es posible que Python / Pandas ya proporcione una solución rápida

pandas e itertools te darán lo que estás buscando.

 import pandas from itertools import chain, combinations def key_options(items): return chain.from_iterable(combinations(items, r) for r in range(1, len(items)+1) ) df = pandas.read_csv('test.csv'); # iterate over all combos of headings, excluding ID for brevity for candidate in key_options(list(df)[1:]): deduped = df.drop_duplicates(candidate) if len(deduped.index) == len(df.index): print ','.join(candidate) 

Esto le da la salida:

 PAYMENT_NUM, END_DATE CUST_NAME, CLIENT_NAME, END_DATE CUST_NAME, PAYMENT_NUM, END_DATE CLIENT_NAME, PAYMENT_NUM, END_DATE PAYMENT_NUM, START_DATE, END_DATE CUST_NAME, CLIENT_NAME, PAYMENT_NUM, END_DATE CUST_NAME, CLIENT_NAME, START_DATE, END_DATE CUST_NAME, PAYMENT_NUM, START_DATE, END_DATE CLIENT_NAME, PAYMENT_NUM, START_DATE, END_DATE CUST_NAME, CLIENT_NAME, PAYMENT_NUM, START_DATE, END_DATE 

Esta es una forma a través de itertools.combinations . Funciona mediante, para cada conjunto de columnas, eliminando duplicados y verificando si el tamaño del dataframe cambia.

Esto resulta en 44 combinaciones distintas de columnas.

 from itertools import combinations, chain full_list = chain.from_iterable(combinations(df, i) for i in range(1, len(df.columns)+1)) n = len(df.index) res = [] for cols in full_list: cols = list(cols) if len(df[cols].drop_duplicates().index) == n: res.append(cols) print(len(res)) # 44