Programmation Python listes

Résolu
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

  1. Contributeur
    bonjour, qu'as-tu essayé?
    0
    1. 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
    2. Contributeur
      @yg_bela 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
  2. 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
    1. 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
    2. 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
    3. Contributeur
      @quent217de 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
    4. @yg_beOui 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
    5. Contributeur
      @quent217je ne pense pas, en tous cas cela ne donne pas le résultat attendu.
      0