In Anbetracht der folgenden zwei Listen möchte ich die Anzahl der Vorkommen jedes in "a" enthaltenen Elements zählen, indem ich es mit dem Wert von "b" gewichte. Python ist 3.7.5.
a = ["A", "B", "C", "A"]
b = [ 1 , 1 , 2 , 2 ]
c = hoge(a, b)
print(c)
Ausgabe
{"A": 3, "B": 1, "C": 2} #Ich möchte diese Art der Ausgabe
#Der Schlüssel und der Wert können getrennt sein
# (["A", "B", "C"], [3, 1, 2])
Angenommen, Sie möchten für jedes Buch die Anzahl der bisher in einem Buchladen verkauften Bücher zählen. [^ 1] Ich habe jedoch nur ** mehrere Tabellendaten, die bereits nach Monat aggregiert wurden **. Stellen wir uns der Einfachheit halber die folgenden zwei CSV-Dateien vor.
■ 2020_01.csv
Buchname | Anzahl der verkauften Bücher |
---|---|
Book_A | 1 |
Book_B | 2 |
Book_C | 3 |
■ 2020_02.csv
Buchname | Anzahl der verkauften Bücher |
---|---|
Book_A | 2 |
Book_C | 1 |
Book_D | 3 |
Das Kombinieren dieser beiden Daten führt zu einem Zählproblem mit "Elementen" und "Gewichten", wie unter "Was Sie tun möchten" beschrieben.
Es wurde nach den folgenden drei Methoden hergestellt. Ich wäre Ihnen dankbar, wenn Sie mir sagen könnten, welche Methode besser ist oder eine andere [^ 2].
Mit der Funktion "bincount" von "numpy" können Sie zählen, während Sie die Eingabe gewichten. Referenz: Bedeutung des Gewichts in numpy.bincount
Jedes Element, das Sie in np.bincount
** eingeben, muss jedoch eine nicht negative Ganzzahl ** sein.
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.
Um "np.bincount" zu verwenden, bereiten Sie daher ein "Etikett" vor, das eindeutig dem Namen des Buches entspricht. Ich habe "LabelEncoder" von "sklearn" verwendet, um "label" zu erstellen.
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder
#Datenaufbereitung
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"])
#Tisch verbinden
df_all = pd.concat([df_01, df_02])
#Der Inhalt ist so.
# | | 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)
#Neue Beschriftungsspalte hinzufügen
df_all["Label"] = encoded
# np.Gewichtete Zählung mit bincount
#Geben Sie zusätzlich zur Spalte Beschriftung die Spalte Anzahl als Gewicht ein. Da das Ergebnis einen Dezimalpunkt hat, konvertiere ich es in int.
count_result = np.bincount(df_all["Label"], weights=df_all["Count"]).astype(int)
#Holen Sie sich den Namen, der dem Ergebnis entspricht
name_result = le.inverse_transform(range(len(result)))
#Erstellen Sie am Ende das gewünschte Wörterbuch
result = dict(zip(name_result, count_result))
print(result)
Ausgabe
{'Book_A': 3, 'Book_B': 2, 'Book_C': 4, 'Book_D': 3}
Sie können auch ein Label mit np.unique erstellen.
Sie können das gleiche Ergebnis wie die "fit_transform" des "LabelEncoder" erzielen, indem Sie das Argument "return_inverse" der "np.unique" auf "True" setzen.
Darüber hinaus können Sie auch sofort den entsprechenden Namen (name_result
oben) abrufen.
# np.Etikettencodierung mit Unique
name_result, encoded = np.unique(df_all["Name"], return_inverse=True)
print(encoded)
print(name_result)
Ausgabe
[0 1 2 0 2 3]
['Book_A' 'Book_B' 'Book_C' 'Book_D']
Eine gewichtete Zählung ist auch möglich, indem die for-Anweisung ohne Verwendung von np.bincount
[^ 3] gedreht wird.
#Erstellen Sie ein mit Nullen aufgefülltes Array mit der gleichen Länge wie das gewünschte Wörterbuch
unique_length = len(name_result)
count_result = np.zeros(unique_length, dtype=int)
#Extrahieren Sie nur die Zeilen in der Tabelle, in denen die Codierung mit i übereinstimmt, und berechnen Sie die Summe der Zählwerte.
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)
Ausgabe
{'Book_A': 3, 'Book_B': 2, 'Book_C': 4, 'Book_D': 3}
Das "Zähler" -Modul der Standardmodul "Sammlungen" wird häufig für die ** ungewichtete ** Zählung eingeführt.
from collections import Counter
a = ["A", "B", "C", "A"]
#Geben Sie Counter eine Liste und zählen Sie ungewichtet
counter = Counter(a)
print(counter)
#Der Zugriff auf Elemente erfolgt wie in einem Wörterbuch
print("A:", counter["A"])
Ausgabe
Counter({'A': 2, 'B': 1, 'C': 1})
A: 2
Wenn es bereits wie dieses Mal aggregiert wurde, können Sie ein Objekt erstellen, indem Sie es im Wörterbuchtyp speichern und dann übergeben.
counter = Counter(dict([["Book_A", 1],
["Book_B", 2],
["Book_C", 3]]))
print(counter)
Ausgabe
Counter({'Book_A': 1, 'Book_B': 2, 'Book_C': 3})
Übrigens kann dieses "Counter" -Objekt berechnet werden. Referenz: Verschiedene Möglichkeiten, um die Anzahl der Vorkommen eines Elements mit Python Counter zu überprüfen
Es scheint, dass dieser Zweck durch Berechnung der Summe erreicht werden kann.
from collections import Counter
a = ["A", "B", "C", "A"]
b = ["C", "D"]
counter_a = Counter(a)
counter_b = Counter(b)
#Kann mit Summe addiert werden
counter_ab = sum([counter_a, counter_b], Counter())
print(counter_ab)
Ausgabe
Counter({'A': 2, 'C': 2, 'B': 1, 'D': 1})
from collections import Counter
#Datenaufbereitung
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"])
#Zähler erstellen
counter_01 = Counter(dict(df_01[["Name", "Count"]].values))
counter_02 = Counter(dict(df_02[["Name", "Count"]].values))
#Berechnen Sie die Summe
# *Ergänzung:Sie können den Anfangswert für das zweite Argument der Summe festlegen.
#Diesmal wird ein leerer Zähler als Anfangswert gesetzt. Der Standardwert ist 0(int)ist.
result = sum([counter_01, counter_02], Counter())
print(result)
Ausgabe
Counter({'Book_C': 4, 'Book_A': 3, 'Book_D': 3, 'Book_B': 2})
~~ Anscheinend sind die Zählungen in absteigender Reihenfolge sortiert. ~~
Wenn Sie dem Wörterbuch mehrere "Werte" für denselben "Schlüssel" geben, wird es durch den zuletzt angegebenen "Wert" überschrieben.
print( {"A": 1, "B": 2, "C": 3, "A":10} )
Ausgabe
{'A': 10, 'B': 2, 'C': 3}
Um den Zählwert eines bestimmten Schlüssels zu aktualisieren, scheint es so, als würde ** der Wert ** des vorhandenen Wörterbuchs abgerufen, ** der hinzuzufügende Wert ** hinzugefügt und am Ende hinzugefügt. Um ein Element nach einem vorhandenen Wörterbuch hinzuzufügen, können Sie das Wörterbuch erweitern, indem Sie der Variablen \ * \ * (zwei Sterne) voranstellen. Referenz: [\ Python ] Funktionsargumente \ * (Stern) und \ * \ * (Doppelstern)
#Vorhandenes Wörterbuch
d = {"A": 1, "B": 2, "C": 3}
#Element zur Wertschöpfung
k = "A"
v = 10
#aktualisieren
d = {**d, k: d[k]+v} # {"A": 1, "B": 2, "C": 3, "A": 1+10}Gleichwertig
print(d)
Ausgabe
{'A': 11, 'B': 2, 'C': 3}
Wenn Sie jedoch einen "Schlüssel" angeben, der nicht im Wörterbuch vorhanden ist, tritt ein Fehler auf, sodass Sie keinen neuen "Schlüssel" hinzufügen können, wie er ist. Verwenden Sie daher die Funktion get () des Wörterbuchobjekts. Sie können get () verwenden, um den Wert festzulegen, der standardmäßig zurückgegeben werden soll, wenn key nicht im Wörterbuch vorhanden ist. Referenz: Wert vom Schlüssel mit get-Methode des Python-Wörterbuchs abrufen (nicht vorhandener Schlüssel ist OK)
d = {"A": 1, "B": 2, "C": 3}
#Geben Sie einen vorhandenen Schlüssel an
print(d.get("A", "NO KEY"))
#Geben Sie einen Schlüssel an, der nicht vorhanden ist
print(d.get("D", "NO KEY"))
Ausgabe
1
NO KEY
Auf diese Weise können Sie Ergänzungen und Aktualisierungen auf die gleiche Weise behandeln, indem Sie den Standardwert auf "0" setzen. Unter Verwendung des obigen Inhalts lautet der Code, der eine gewichtete Zählung durch Hinzufügen / Aktualisieren von Werten zu einem leeren Wörterbuch durchführt, wie folgt.
import pandas as pd
from itertools import chain
#Datenaufbereitung
import pandas as pd
from itertools import chain
from functools import reduce
#Datenaufbereitung
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"])
#Datenrahmen in Wörterbuch konvertieren
data1 = dict(df_01[["Name", "Count"]].values)
data2 = dict(df_02[["Name", "Count"]].values)
#Funktionsdefinition
chain_items = lambda data : chain.from_iterable( d.items() for d in data ) #Kombinieren Sie mehrere Wörterbücher"Schlüssel- und Wertepaar"Funktion, die zurückgibt
add_elem = lambda acc, e : { **acc, e[0]: acc.get(e[0], 0) + e[1] } #Eine Funktion, die dem Wörterbuch Elemente hinzufügt und Werte aktualisiert
#Eine Funktion, die mehrere Wörterbücher empfängt und zusammenführt, wobei der Schlüssel ein Element und der Wert ein Gewicht ist
def merge_count(*data) :
result = {}
for e in chain_items(data) :
result = add_elem(result, e)
return result
print( merge_count(data1, data2) )
Ausgabe
{'A': 3, 'B': 2, 'C': 4, 'D': 3}
Mit "Reduzieren" ist eine iterative Verarbeitung möglich, ohne eine for-Anweisung zu schreiben.
reduct
akzeptiert die folgenden Argumente.
from functools import reduce
func = lambda ans, x: ans * x
a = [1, 2, 3, 4]
start = 10
print(reduce(func, a, start))
Ausgabe
240 # 10*1 = 10
# -> 10*2 = 20
# -> 20*3 = 60
# -> 60*4 = 240
Das Wiederherstellen des obigen "merge_count" mit "reduzieren" ergibt:
from functools import reduce
merge_count = lambda *data : reduce( add_elem, chain_items(data), {} ) #Oben zusammenführen_Entspricht der Zählung
print( merge_count(data1, data2) )
Ausgabe
{'A': 3, 'B': 2, 'C': 4, 'D': 3}
Die folgende Seite war sehr hilfreich für "Reduzieren". Referenz: Einführung in die funktionale Programmierung
Bedeutung des Gewichts in numpy.bincount [Codierung von Kategorievariablen] (https://qiita.com/ground0state/items/f516b97c7a8641e474c4)
[[Python] Zählen von Listenelementen, Verwendung von Sammlungen.Counter] (https://qiita.com/ellio08/items/259388b511e24625c0d7) [Verschiedene Möglichkeiten, um die Anzahl der Vorkommen eines Elements mit Python Counter zu überprüfen] (https://www.headboost.jp/python-counter/)
[\ [Python ] Funktionsargumente \ * (Stern) und \ * \ * (Doppelstern)] (https://qiita.com/supersaiakujin/items/faee48d35f8d80daa1ac) [Einführung in die funktionale Programmierung] (https://postd.cc/an-introduction-to-functional-programming/)
[^ 1]: Ich habe ein geeignetes konkretes Beispiel gegeben, um die Übermittlung zu erleichtern, aber in Wirklichkeit wurde es verwendet, um die morphologischen Analyseergebnisse mehrerer Dokumente zu aggregieren. [^ 2]: Ausführungsgeschwindigkeit, Speichereffizienz usw. [^ 3]: Ich konnte mir nichts anderes vorstellen, als mit meinem eigenen Wissen eine for-Anweisung zu schreiben ... (ohne Notation zur Aufnahme von Listen).
Recommended Posts