Une autre question, mineure : est-ce une mauvaise pratique que d'avoir des non uniques ?
Ce n'est pas une grande pratique, mais cela dépend de vos besoins et peut être correct dans certaines circonstances.
Numéro 1 : opérations de jonction
Un bon point de départ est de penser à Qu'est-ce qui différencie un index d'une colonne standard de DataFrame ? . Cela pose la question suivante : si votre index a des valeurs en double, doit-il vraiment être spécifié comme un index, ou peut-il simplement être une autre colonne dans un fichier de type RangeIndex
-ed DataFrame ? Si vous avez déjà utilisé SQL ou tout autre DMBS et que vous souhaitez imiter les opérations de jointure dans pandas avec des fonctions telles que .join
o .merge
vous perdrez la fonctionnalité d'un clé primaire si vous avez des valeurs d'index en double. Une fusion vous donnera ce qui est fondamentalement un produit cartésien - probablement pas ce que vous recherchez.
Par exemple :
df = pd.DataFrame(np.random.randn(10,2),
index=2*list('abcde'))
df2 = df.rename(columns={0: 'a', 1 : 'b'})
print(df.merge(df2, left_index=True, right_index=True).head(7))
0 1 a b
a 0.73737 1.49073 0.73737 1.49073
a 0.73737 1.49073 -0.25562 -2.79859
a -0.25562 -2.79859 0.73737 1.49073
a -0.25562 -2.79859 -0.25562 -2.79859
b -0.93583 1.17583 -0.93583 1.17583
b -0.93583 1.17583 -1.77153 -0.69988
b -1.77153 -0.69988 -0.93583 1.17583
Question 2 : la performance
Les indices à valeur unique rendent certaines opérations efficaces, comme l'explique le document ce poste.
Lorsque l'index est unique, pandas utilise une table de hachage pour faire correspondre la clé à la valeur O(1). Lorsque l'index est non-unique et trié, les pandas utilisent la recherche binaire O(logN), lorsque l'index est aléatoire et ordonné, les pandas doivent vérifier toutes les clés de l'index l'index O(N).
Un mot sur .loc
Utilisation de .loc
retournera toutes les instances de l'étiquette. Cela peut être une bénédiction ou une malédiction en fonction de votre objectif. Par exemple,
df = pd.DataFrame(np.random.randn(10,2),
index=2*list('abcde'))
print(df.loc['a'])
0 1
a 0.73737 1.49073
a -0.25562 -2.79859