Comment compter le nombre d'occurrences de chaque élément de la liste en Python avec poids

Chose que tu veux faire

Étant donné les deux listes suivantes, je veux compter le nombre d'occurrences de chaque élément inclus dans «a» en le pondérant avec la valeur de «b». Python est 3.7.5.

a = ["A", "B", "C", "A"]
b = [ 1 ,  1 ,  2 ,  2 ]

c = hoge(a, b)
print(c)

production


{"A": 3, "B": 1, "C": 2}  #Je veux ce genre de sortie

#La clé et la valeur peuvent être séparées
# (["A", "B", "C"], [3, 1, 2])

Exemple spécifique de ce que vous voulez faire

Supposons que vous souhaitiez compter le nombre de livres vendus jusqu'à présent dans une librairie pour chaque livre. [^ 1] Cependant, je n'ai que ** plusieurs données de table qui ont déjà été agrégées par mois **. Par souci de simplicité, imaginons les deux fichiers csv suivants.

■ 2020_01.csv

Nom du livre Nombre de livres vendus
Book_A 1
Book_B 2
Book_C 3

■ 2020_02.csv

Nom du livre Nombre de livres vendus
Book_A 2
Book_C 1
Book_D 3

La combinaison de ces deux données entraîne un problème de comptage avec des «éléments» et des «poids» comme décrit dans «Ce que vous voulez faire».

Méthode

Il a été fabriqué par les trois méthodes suivantes. Je vous serais reconnaissant si vous pouviez me dire laquelle est la meilleure ou une autre méthode [^ 2].

  1. Rejoignez toutes les tables, créez une étiquette qui correspond uniquement au nom du livre et comptez le poids avec numpy.bincount.
  2. Créez un objet collections.Counter pour chaque table et ajoutez les objets Counter pour toutes les tables.
  3. Utilisez l'instruction for pour ajouter des éléments au dictionnaire et mettre à jour les valeurs. 3 '. Utilisez reduction au lieu de l'instruction for.

1. Utilisez numpy.bincount

En utilisant la fonction bincount de numpy, vous pouvez compter tout en pondérant l'entrée. Référence: Signification du poids dans numpy.bincount

Cependant, chaque élément que vous entrez dans np.bincount ** doit être un entier non négatif **.

numpy.bincount(x, weights=None, minlength=0) Count number of occurrences of each value in array of non-negative ints.

x : array_like, 1 dimension, nonnegative ints ---- Input array. weights : array_like, optional ---- Weights, array of the same shape as x. minlength : int, optional ---- A minimum number of bins for the output array. ---- New in version 1.6.0.

Par conséquent, pour utiliser «np.bincount», préparez une «étiquette» qui correspond uniquement au nom du livre. J'ai utilisé «LabelEncoder» de «sklearn» pour créer «label».

code

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder

#Préparation des données
df_01 = pd.DataFrame([["Book_A", 1],
                      ["Book_B", 2],
                      ["Book_C", 3]],
                     columns=["Name", "Count"])
df_02 = pd.DataFrame([["Book_A", 2],
                      ["Book_C", 1],
                      ["Book_D", 3]],
                     columns=["Name", "Count"])

#Joindre la table
df_all = pd.concat([df_01, df_02])
#Le contenu est comme ça.
# |  | Name | Count |
# |--:|:--|--:|
# | 0 | Book_A | 1 |
# | 1 | Book_B | 2 |
# | 2 | Book_C | 3 |
# | 0 | Book_A | 2 |
# | 1 | Book_C | 1 |
# | 2 | Book_D | 3 |

#LabelEncoder
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
encoded = le.fit_transform(df_all['Name'].values)

#Ajouter une nouvelle colonne d'étiquette
df_all["Label"] = encoded

# np.Comptage pondéré avec bincount
#En plus de la colonne Libellé, saisissez la colonne Nombre comme poids. Comme le résultat a un point décimal, je le convertis en int.
count_result = np.bincount(df_all["Label"], weights=df_all["Count"]).astype(int)
#Obtenez le nom correspondant au résultat
name_result = le.inverse_transform(range(len(result)))

#Créez le dictionnaire que vous voulez à la fin
result = dict(zip(name_result, count_result))
print(result)

production


{'Book_A': 3, 'Book_B': 2, 'Book_C': 4, 'Book_D': 3}

Supplément

Vous pouvez également créer une étiquette en utilisant np.unique. Vous pouvez obtenir le même résultat que fit_transform de LabelEncoder en définissant l'argument return_inverse de np.unique sur True. De plus, vous pouvez également obtenir le nom correspondant (name_result ci-dessus) à la fois.

# np.Encodage d'étiquettes à l'aide d'un
name_result, encoded = np.unique(df_all["Name"], return_inverse=True)
print(encoded)
print(name_result)

production


[0 1 2 0 2 3]
['Book_A' 'Book_B' 'Book_C' 'Book_D']

De plus, le comptage pondéré est possible en tournant l'instruction for sans utiliser np.bincount [^ 3].

#Créez un tableau rempli de zéro avec la même longueur que le dictionnaire souhaité
unique_length = len(name_result)
count_result = np.zeros(unique_length, dtype=int)

#Extrayez uniquement les lignes de la table où codé correspond à i et calculez la somme des valeurs Count.
for i in range(unique_length):
    count_result[i] = df_all.iloc[encoded==i]["Count"].sum().astype(int)

result = dict(zip(name_result, count_result))
print(result)

production


{'Book_A': 3, 'Book_B': 2, 'Book_C': 4, 'Book_D': 3}

2. Utilisez les collections.

Vue d'ensemble des collections.

Le module Counter des collections du module standard` sera souvent introduit pour le comptage ** non pondéré **.

from collections import Counter

a = ["A", "B", "C", "A"]

#Donnez à Counter une liste et faites un comptage non pondéré
counter = Counter(a)
print(counter)

#L'accès aux éléments est le même que dans un dictionnaire
print("A:", counter["A"])

production


Counter({'A': 2, 'B': 1, 'C': 1})
A: 2

De plus, s'il a déjà été agrégé comme cette fois, vous pouvez créer un objet en le stockant dans le type de dictionnaire, puis en le passant.

counter = Counter(dict([["Book_A", 1],
                        ["Book_B", 2],
                        ["Book_C", 3]]))
print(counter)

production


Counter({'Book_A': 1, 'Book_B': 2, 'Book_C': 3})

Calcul à l'aide de Counter

D'ailleurs, cet objet Counter peut être calculé. Référence: Différentes manières de vérifier le nombre d'occurrences d'un élément avec Python Counter

Il semble que cet objectif puisse être atteint en calculant la somme.

from collections import Counter

a = ["A", "B", "C", "A"]
b = ["C", "D"]

counter_a = Counter(a)
counter_b = Counter(b)

#Peut être ajouté avec somme
counter_ab = sum([counter_a, counter_b], Counter())
print(counter_ab)

production


Counter({'A': 2, 'C': 2, 'B': 1, 'D': 1})

code

from collections import Counter

#Préparation des données
df_01 = pd.DataFrame([["Book_A", 1],
                      ["Book_B", 2],
                      ["Book_C", 3]],
                     columns=["Name", "Count"])
df_02 = pd.DataFrame([["Book_A", 2],
                      ["Book_C", 1],
                      ["Book_D", 3]],
                     columns=["Name", "Count"])

#Créer un compteur
counter_01 = Counter(dict(df_01[["Name", "Count"]].values))
counter_02 = Counter(dict(df_02[["Name", "Count"]].values))

#Calculez la somme
# *Supplément:Vous pouvez définir la valeur initiale du deuxième argument de sum.
#Cette fois, un compteur vide est défini comme valeur initiale. La valeur par défaut est 0(int)est.
result = sum([counter_01, counter_02], Counter())
print(result)

production


Counter({'Book_C': 4, 'Book_A': 3, 'Book_D': 3, 'Book_B': 2})

~~ Apparemment, les nombres sont triés par ordre décroissant. ~~

3. Ajoutez des éléments au dictionnaire et mettez à jour les valeurs avec l'instruction for

Ajout d'éléments au dictionnaire et mise à jour des valeurs

Si vous donnez au dictionnaire plusieurs «valeurs» pour la même «clé», elle sera écrasée par la dernière «valeur» donnée.

print( {"A": 1, "B": 2, "C": 3, "A":10} )

production


{'A': 10, 'B': 2, 'C': 3}

En utilisant cela, afin de mettre à jour la valeur de comptage d'une certaine clé, il semble que ** récupère la valeur ** du dictionnaire existant, ajoute ** la valeur ** à ajouter et l'ajoute à la fin. De plus, pour ajouter un élément après un dictionnaire existant, vous pouvez développer le dictionnaire en ajoutant \ * \ * (deux étoiles) à la variable. Référence: [\ Python ] arguments de fonction \ * (étoile) et \ * \ * (étoile double)

#Dictionnaire existant
d = {"A": 1, "B": 2, "C": 3}

#Élément à valeur ajoutée
k = "A"
v = 10
#mise à jour
d = {**d, k: d[k]+v}    # {"A": 1, "B": 2, "C": 3, "A": 1+10}Équivalent à

print(d)

production


{'A': 11, 'B': 2, 'C': 3}

Cependant, si vous spécifiez une «clé» qui n'existe pas dans le dictionnaire, une erreur se produira, vous ne pouvez donc pas ajouter une nouvelle «clé» telle quelle. Par conséquent, utilisez la fonction get () de l'objet dictionnaire. Vous pouvez utiliser get () pour définir la valeur à renvoyer par défaut lorsque key n'existe pas dans le dictionnaire. Référence: Obtenir la valeur de la clé avec la méthode get du dictionnaire Python (la clé qui n'existe pas est OK)

d = {"A": 1, "B": 2, "C": 3}

#Spécifiez une clé existante
print(d.get("A", "NO KEY"))
#Spécifiez une clé qui n'existe pas
print(d.get("D", "NO KEY"))

production


1
NO KEY

Cela vous permet de gérer les ajouts et les mises à jour de la même manière en définissant la valeur par défaut sur «0». En utilisant le contenu ci-dessus, le code qui effectue le comptage pondéré en ajoutant / mettant à jour des valeurs dans un dictionnaire vide est le suivant.

code

import pandas as pd
from itertools import chain

#Préparation des données
import pandas as pd
from itertools import chain
from functools import reduce

#Préparation des données
df_01 = pd.DataFrame([["Book_A", 1],
                      ["Book_B", 2],
                      ["Book_C", 3]],
                     columns=["Name", "Count"])
df_02 = pd.DataFrame([["Book_A", 2],
                      ["Book_C", 1],
                      ["Book_D", 3]],
                     columns=["Name", "Count"])
#Convertir le bloc de données en dictionnaire
data1 = dict(df_01[["Name", "Count"]].values)
data2 = dict(df_02[["Name", "Count"]].values)

#Définition des fonctions
chain_items = lambda data : chain.from_iterable( d.items() for d in data )  #Combinez plusieurs dictionnaires"paire clé et valeur"Fonction qui retourne
add_elem = lambda acc, e : { **acc, e[0]: acc.get(e[0], 0) + e[1] }  #Une fonction qui ajoute des éléments au dictionnaire et met à jour les valeurs

#Une fonction qui reçoit et fusionne plusieurs dictionnaires où la clé est un élément et la valeur est un poids
def merge_count(*data) :
    result = {}
    for e in chain_items(data) :
        result = add_elem(result, e)
    return result

print( merge_count(data1, data2) )

production


{'A': 3, 'B': 2, 'C': 4, 'D': 3}

Utilisez réduire au lieu de 3 pour l'instruction

Avec «réduire», le traitement itératif est possible sans écrire une instruction for. réduire prend les arguments suivants.

from functools import reduce

func = lambda ans, x: ans * x
a = [1, 2, 3, 4]
start = 10

print(reduce(func, a, start))

production


240  #    10*1 = 10
     # -> 10*2 = 20
     # -> 20*3 = 60
     # -> 60*4 = 240

Si vous reproduisez le merge_count ci-dessus à l'aide de réduire, ce sera comme suit.

from functools import reduce

merge_count = lambda *data : reduce( add_elem, chain_items(data), {} )    #Fusionner ci-dessus_Équivalent à compter
print( merge_count(data1, data2) )

production


{'A': 3, 'B': 2, 'C': 4, 'D': 3}

Le site suivant a été très utile pour «réduire». Référence: Introduction à la programmation fonctionnelle

Page référencée

Signification du poids dans numpy.bincount [Codage de variable de catégorie] (https://qiita.com/ground0state/items/f516b97c7a8641e474c4)

[[Python] Comptage des éléments de liste, comment utiliser les collections. Compteur] (https://qiita.com/ellio08/items/259388b511e24625c0d7) [Différentes façons de vérifier le nombre d'occurrences d'un élément avec Python Counter] (https://www.headboost.jp/python-counter/)

[\ [Python ] arguments de fonction \ * (étoile) et \ * \ * (double étoile)] (https://qiita.com/supersaiakujin/items/faee48d35f8d80daa1ac) [Introduction à la programmation fonctionnelle] (https://postd.cc/an-introduction-to-functional-programming/)

[^ 1]: J'ai donné un exemple concret approprié pour le rendre plus facile à transmettre, mais en réalité il a été utilisé pour agréger les résultats d'analyse morphologique de plusieurs documents. [^ 2]: Vitesse d'exécution, efficacité de la mémoire, etc ... [^ 3]: Je ne pouvais penser à rien d'autre que d'écrire une instruction for avec mes propres connaissances ... (à l'exclusion de la notation d'inclusion de liste).

Recommended Posts

Comment compter le nombre d'occurrences de chaque élément de la liste en Python avec poids
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
Obtenez le nombre d'occurrences pour chaque élément de la liste
Comment obtenir le nombre de chiffres en Python
Comment obtenir une liste de fichiers dans le même répertoire avec python
[Homologie] Comptez le nombre de trous dans les données avec Python
Comment déterminer l'existence d'un élément sélénium en Python
[Python] Comment mettre n'importe quel nombre d'entrées standard dans la liste
[Python] Comment afficher les valeurs de liste dans l'ordre
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
Comment compter le nombre d'éléments dans Django et sortir dans le modèle
Comparez la somme de chaque élément dans deux listes avec la valeur spécifiée en Python
4 méthodes pour compter le nombre d'occurrences d'entiers dans un certain intervalle (y compris la méthode imos) [implémentation Python]
[Version terminée] Essayez de connaître le nombre d'habitants de la ville à partir de la liste d'adresses avec Python
Comment trouver le nombre optimal de clusters pour les k-moyennes
Obtenez le nombre d'éléments spécifiques dans la liste python
python: Astuces pour afficher un tableau (liste) avec un index (comment savoir quel numéro est un élément d'un tableau)
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Comment obtenir une liste d'exceptions intégrées pour python
Comment vérifier en Python si l'un des éléments d'une liste est dans une autre liste
Obtenez l'index de chaque élément de la matrice de confusion en Python
Comment trouver le premier élément qui correspond aux critères de la liste Python
Comment compter rapidement la fréquence d'apparition des caractères à partir d'une chaîne de caractères en Python?
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python (version non bloquante)
Comptez bien le nombre de caractères thaïlandais et arabes en Python
Comment connaître la structure interne d'un objet en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
Visualisez la fréquence des occurrences de mots dans les phrases avec Word Cloud. [Python]
python Remarque: map -faire la même chose pour chaque élément de la liste
Résumé de l'utilisation de la liste Python
Compter le nombre de caractères avec écho
Voyons comment compter le nombre d'éléments dans un tableau dans certains langages [Go, JavaScript, PHP, Python, Ruby, Swift]
Comment obtenir la différence de date et d'heure en secondes avec Python
Obtenez le nombre de visites sur chaque page avec ReportingAPI + Cloud Functions
[Python] Comment utiliser la fonction enumerate (extraire le numéro d'index et l'élément)
[Python] Comment utiliser la liste 2 Référence de la valeur de la liste, nombre d'éléments, valeur maximale, valeur minimale
Recevez une liste des résultats du traitement parallèle en Python avec starmap
Comment utiliser la bibliothèque C en Python
Sortie du nombre de cœurs de processeur en Python
[Python] Trier la liste de pathlib.Path dans l'ordre naturel
[REAPER] Comment jouer à Reascript avec Python
Comment effacer un taple dans une liste (Python)
Faites correspondre la distribution de chaque groupe en Python
Calculez le nombre total de combinaisons avec python
Copiez la liste en Python
Résumé de l'utilisation de MNIST avec Python
Comment spécifier des attributs avec Mock of Python
[Algorithm x Python] Comment utiliser la liste
Comment obtenir les fichiers dans le dossier [Python]
Comment utiliser tkinter avec python dans pyenv
Comment supprimer les éléments en double dans la liste Python 3
Comptez le nombre de fois que deux valeurs apparaissent simultanément dans un élément de type itérateur Python 3
traitement (python) Diagramme les coordonnées de la liste Spécifiez le nombre de fois dans draw ()
[python] Comment trier par le Nth Mth élément d'un tableau multidimensionnel
Comment trouver le coefficient de la courbe approximative passant par les sommets en Python
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
[Python] Comment supprimer les valeurs en double de la liste