Programmation Python listes

Résolu/Fermé
HofmanC Messages postés 4 Date d'inscription vendredi 7 août 2020 Statut Membre Dernière intervention 7 août 2020 - 7 août 2020 à 10:17
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 - 7 août 2020 à 22:41
Bonjour à tous

Voici mon problème :

J'ai deux listes :
Index list: [0, 5, 5, 6, 0, 1, 1, 8, 9, 9]
Index list Mfccs : [0.640495, 0.4822588, 0.6523488, 0.74474275, 0.5423001, 0.85711163, 0.724612, 0.5099624, 0.9696293, 0.97258127]



La deuxième liste contient les valeurs réels et la première, les arguments des valeurs de la deuxième.

Mon but est de choisir dans le première liste, l'argument qui ressort le plus souvent.
C'est facile lorsqu'il n'y a pas deux doublons comme dans une liste comme celle-ci :

Index list: [1, 6, 6, 6, 6, 9, 6, 2, 6, 2]


Ici je ressort donc l'argument 6. avec une simple ligne de code :

predicted_index = np.bincount(Index list).argmax()


Mais dans le cas du début, j'ai 4 doublons ! Deux 0, deux 5, deux 1 et deux 9.
Je veux donc récupérer les valeurs réels de tous ces chiffres (dans la liste Index list Mfccs), les comparer et ne ressortir que la valeur maximale.
Je voudrais faire de même si une liste qui ressort deux valeurs trois fois comme celle-ci :

Index list: [1, 4, 3, 4, 4, 9, 6, 5, 5, 5]


Etc.

Merci d'avance pour votre aide,



Configuration: Windows / Chrome 84.0.4147.105

2 réponses

yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 Ambassadeur 1 557
7 août 2020 à 10:24
bonjour, qu'as-tu essayé?
0
HofmanC Messages postés 4 Date d'inscription vendredi 7 août 2020 Statut Membre Dernière intervention 7 août 2020
7 août 2020 à 11:02
Bonjour yg_be,

J'ai essayé deux méthodes :
Méthode 1 :

Utiliser un histogramme. C'est la méthode la plus efficace et rapide que j'ai trouvé pour le moment mais malheureusement, elle ne fonctionne pas dans tous les cas et je n'arrive pas à savoir ce qui bloque. Voici le code :
import matplotlib.pyplot as mat


idx=[1, 1, 4, 4, 5, 6, 7, 9, 8, 0]
val=[0.640495, 0.4822588, 0.6523488, 0.74474275, 0.5423001, 0.85711163, 0.724612, 0.5099624, 0.9696293, 0.97258127]

#Histogramme des index et de leur répétition
histog=mat.hist(idx)
histo=dict((n, idx.count(n)) for n in set(idx))
print(histo)

#Extraction des index répétés le max
extract=tuple(k for (k, v) in histo.items() if v == max(histo.values()))
print(extract)

#Affichage de la valeur la plus forte prise parmis les index extraits
print(max(val[n] for n in extract))


Le code est ici censé nous rendre la valeur la plus élevée entre les valeurs des deux 1 et des deux 4 soit 0.74. Mais le résultat est le suivant :
runfile('C:/Users/c.hofman.BORDEAUX/Desktop/Codes python/04 Son/Genre Classification/Liste.py', wdir='C:/Users/c.hofman.BORDEAUX/Desktop/Codes python/04 Son/Genre Classification')
{0: 1, 1: 2, 4: 2, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1}
(1, 4)
0.5423001






Deuxième méthode :
Méthode plus longue et plus "brouillon" ;)
Je passe par une boucle for et je liste les cas possibles. Comme je veux sélectionner seulement les groupes les plus nombreux, s'il y a un doublons et un triplé, je ne veux que la valeur la plus élevée du triplé, je retire donc de la liste les valeurs du doublons avec un if.
Malheureusement, cela fonctionne seulement si les doublons se trouve avant les triplés dans la liste de départ.

Voici mon code :

index_list = [9, 3, 1, 6, 4, 9, 5, 8, 1, 9]
index_list_mcfccs = [0.640495, 0.4822588, 0.6523488, 0.74474275, 0.5423001, 0.85711163, 0.724612, 0.5099624, 0.9696293, 0.97258127]

result_mcfccs = []
result2 = 0
result3 = 0
result4 = 0
result5 = 0


for idx, index in enumerate(index_list):
if index_list.count(index) == 2:
result_mcfccs.append(index_list_mcfccs[idx])
result2 = max(result_mcfccs)
print("2 ", result2)
elif index_list.count(index) == 3:
result_mcfccs.append(index_list_mcfccs[idx])

if result2 in result_mcfccs:
result_mcfccs.remove(result2)

result3 = max(result_mcfccs)
print("3 ", result3)

elif index_list.count(index) == 4:
result_mcfccs.append(index_list_mcfccs[idx])

if (result2, result3) in result_mcfccs:
result_mcfccs.remove(result2, result3)

result4 = max(result_mcfccs)
print("4 ", result4)

elif index_list.count(index) == 5:
result_mcfccs.append(index_list_mcfccs[idx])

if (result2, result3, result4) in result_mcfccs:
result_mcfccs.remove(result2, result3, result4)

result5 = max(result_mcfccs)
print("5 ", result5)



print("Résultat final : ", result_mcfccs)
print("Résultat final : ", max(result_mcfccs))
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > HofmanC Messages postés 4 Date d'inscription vendredi 7 août 2020 Statut Membre Dernière intervention 7 août 2020
Modifié le 7 août 2020 à 12:06
peux-tu utiliser les balises de code et préciser "python" quand tu postes du codepython: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
j'ai examiné l'histogramme.
il me semble que tu te prends les pieds dans tes données et dans le nom des variables.
la première liste ne contient pas des index à utiliser dans la seconde.
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024
7 août 2020 à 12:10
la seconde méthode me semble totalement incorrecte.
avant d'écrire du code, prends le temps de te demander comment tu ferais cela à la main, avec une feuille et un crayon. quand tu as trouvé une bonne méthode, tu peux commencer à la programmer.
0
HofmanC Messages postés 4 Date d'inscription vendredi 7 août 2020 Statut Membre Dernière intervention 7 août 2020
7 août 2020 à 12:40
Bonjour,

J'ai finalement, trouvé une solution qui utilise un compromis entre les deux méthodes en une seule boucle for !

J'utilise l'histogramme. Mais je ne sélectionne que les valeurs des index se répétant le plus.

Voici le code :

index_list = [1, 1, 1, 3, 5, 4, 7, 9, 9, 0]
mfccs_list = [0.640495, 0.4822588, 0.6523488, 0.74474275, 0.5423001, 0.85711163, 0.724612, 0.5099624, 0.9696293, 0.97258127]

# Histogramme des index et de leur répétition
histogram = dict((n, index_list.count(n)) for n in set(index_list))

print("Histogramme : ","\n", histogram)
#print ("\nItems de l'histogramme : ","\n", histogram.items())
print ("\nNbre d'apparation des index : ","\n", histogram.values())
print ("\nMaximum d'apparitions d'un même index : ", max(histogram.values()))

result_mcfccs = []

for m, n in enumerate(index_list):
if index_list.count(n) == max (histogram.values()):
result_mcfccs.append(mfccs_list[m])
print("\nListe des Mfccs des index apparaissants le plus :","\n", result_mcfccs)
result2 = max(result_mcfccs)
print("\nRésultat final :", result2)


Résultat :

runfile('C:/Users/c.hofman.BORDEAUX/Desktop/Codes python/04 Son/Genre Classification/Liste.py', wdir='C:/Users/c.hofman.BORDEAUX/Desktop/Codes python/04 Son/Genre Classification')
Histogramme :
{0: 1, 1: 3, 3: 1, 4: 1, 5: 1, 7: 1, 9: 2}

Nbre d'apparation des index :
dict_values([1, 3, 1, 1, 1, 1, 2])

Maximum d'apparitions d'un même index : 3

Liste des Mfccs des index apparaissants le plus :
[0.640495, 0.4822588, 0.6523488]

Résultat final : 0.6523488


Ainsi même si un doublons est présent avec un triplé, les valeurs du doublons ne seront pas prises en compte.

Merci encore pour l'aide apportée !
Bien Cordialement
Hofman
0
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 347
7 août 2020 à 15:36
Bonjour,
si je peux me permettre, votre code fonctionne mais il n'est pas du tout efficace. Tant que les listes d'entrée sont petites ça ne change pas grand chose, mais si vous utilisez des grandes listes, la différence se fera sentir.

Pourtant il y a quelques éléments simples que vous pouvez corriger.
Déjà vous calculez le nombre d'occurences de chaque éléments à la ligne 5, et vous refaites le même calcul à la ligne 15 plutôt que de réutiliser les résulats. Vous pourriez faire
if histogram[n] == max (histogram.values()):


Ensuite vous recalculez le max de l'histogramme à chaque passage dans la boucle à la ligne 15 alors que vous pourriez stocker cette information dans un variable avant la boucle étant donnée qu'elle reste constante.

Vous pourriez aussi optimiser la boucle car vous itérez sur la liste qui contient beaucoup de doublons. Il serait plus rapide d'itérer sur le dictionnaire (l'histogramme) qui contient les mêmes informations mais sans les doublons.

Voilà les choses que vous pouvez corriger très simplement.
Mais de manière générale, votre algorithme a une complexité quadratique alors que vous pourriez le faire avec une complexité linéaire. C'est le cas notamment de la ligne 5 car la méthode count va elle même itérer sur toute la liste alors que vous pourriez parcourir une seule fois la liste et mettant à jour le dictionnaire pour chaque élément.

Bonne journée
0
HofmanC Messages postés 4 Date d'inscription vendredi 7 août 2020 Statut Membre Dernière intervention 7 août 2020
7 août 2020 à 15:37
Petit "update" de mon résultat final avec deux méthodes qui fonctionnent, la méthode 2, avec la liste étant, je trouve, la meilleure des deux !

#%% Méthode avec des histogrammes :

from collections import Counter

index_list = [1, 1, 1, 2, 2, 4, 7, 9, 9, 0]
mfccs_list = [0.640495, 0.4822588, 0.6523488, 0.74474275, 0.5423001, 0.85711163, 0.724612, 0.5099624, 0.9696293, 0.97258127]

# # Histogramme des index et de leur répétition
# histogram = dict((n, index_list.count(n)) for n in set(index_list))

# print("Histogramme : ","\n", histogram)
# print ("\nItems de l'histogramme : ","\n", histogram.items())
# print ("\nNbre d'apparation des index : ","\n", histogram.values())
# print ("\nMaximum d'apparitions d'un même index : ", max(histogram.values()))

# result_mcfccs = []

# for m, n in enumerate(index_list):
# if index_list.count(n) == max (histogram.values()):
# result_mcfccs.append(mfccs_list[m])
# print("\nListe des Mfccs des index apparaissants le plus :","\n", result_mcfccs)
# result2 = max(result_mcfccs)
# print("\nRésultat final :", result2)


# extract=tuple(k for (k, v) in histogram.items() if v == max(histogram.values()))
# print(extract)

# indices = list(map(lambda x: x[0], Counter(index_list).most_common()))
# counts = list(map(lambda x: x[1], Counter(index_list).most_common()))
# max_indices = [indices[i] for i, x in enumerate(counts) if x == max(counts)]

# print(max_indices)





#%% Méthode avec une liste :

result_mcfccs = []



indices = list(map(lambda x: x[0], Counter(index_list).most_common()))
counts = list(map(lambda x: x[1], Counter(index_list).most_common()))

print("\nIndices présents dans la liste : ", indices)
print("\nNombre d'apparition des indices : ", counts)

max_indices = [indices[i] for i, x in enumerate(counts) if x == max(counts)]


for idx, id in enumerate(index_list):
if id in max_indices:
result_mcfccs.append(mfccs_list[idx])


result = max(result_mcfccs)


print("\n Indice se répétant le plus : ", max_indices)
print("\n Valeur des indices se répétant le plus : ","\n",result_mcfccs)
print("\n Valeur maximale de l'indice se répétant le plus : ",result)



indice = mfccs_list.index(result)
print("\nEmplacement de la valeur dans la lsite :",indice)

print("\nRésultat final : ", index_list.pop(indice))








Merci encore
Cordialement
Hofman
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024
7 août 2020 à 15:48
de plus, au lieu de créer la liste result_mcfccs pour en calculer ensuite le maximum, il est plus efficace de calculer le maximum dans la boucle, au lieu de créer la liste, qui ne sert à rien d'autre:
maxhv=max (histogram.values())
result2=float('-inf') 
for  m,n in enumerate(index_list):
    if index_list.count(n) == maxhv:
        if mfccs_list[m]>result2:
            result2=mfccs_list[m]
0
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 347 > yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024
7 août 2020 à 16:19
Oui effectivement, et on pourrait même simplifier encore plus en utilisant la fonction max de python :)
maxhv = max(histogram.values()) 
result2 = max(mfccs_list[key] for key, value in histogram.items() if value == maxhv)
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024
Modifié le 7 août 2020 à 18:27
je ne pense pas, en tous cas cela ne donne pas le résultat attendu.
0