Zählen Sie die Häufigkeit, mit der ein Wert in einer Datenrahmenspalte auftritt


313

Ich habe einen Datensatz

|category|
cat a
cat b
cat a

Ich möchte in der Lage sein, etwas zurückzugeben wie (eindeutige Werte und Häufigkeit anzeigen)

category | freq |
cat a       2
cat b       1



Bei Verwendung von "df [" category "]. Value_counts ()" heißt es, es sei ein int? aber es gibt den Spaltennamen als Index zurück? Ist es ein Datenrahmenobjekt oder kombiniert es irgendwie eine Reihe (die Anzahl) und die ursprünglichen eindeutigen Spaltenwerte?
Yoshiserry

@yoshiserry es ist eine Pandas-Serie zu tun type(df['category'].value_counts())und es wird so sagen
EdChum

Ich habe es getan, und das hat mich überrascht, aber es macht Sinn, je mehr ich darüber nachdenke. Danach zählt der Wert für einige Spalten. Es gibt Zeilen, die ich ausschließen möchte. Ich weiß, wie man Spalten entfernt, aber wie schließe ich Zeilen aus?
Yoshiserry

Antworten:


414

Verwenden Sie groupbyund count:

In [37]:
df = pd.DataFrame({'a':list('abssbab')})
df.groupby('a').count()

Out[37]:

   a
a   
a  2
b  3
s  2

[3 rows x 1 columns]

Siehe die Online-Dokumente: http://pandas.pydata.org/pandas-docs/stable/groupby.html

Auch value_counts()wie @DSM kommentiert hat, gibt es hier viele Möglichkeiten, eine Katze zu häuten

In [38]:
df['a'].value_counts()

Out[38]:

b    3
a    2
s    2
dtype: int64

Wenn Sie dem ursprünglichen Datenrahmen wieder Frequenz hinzufügen möchten, verwenden Sie Folgendes transform, um einen ausgerichteten Index zurückzugeben:

In [41]:
df['freq'] = df.groupby('a')['a'].transform('count')
df

Out[41]:

   a freq
0  a    2
1  b    3
2  s    2
3  s    2
4  b    3
5  a    2
6  b    3

[7 rows x 2 columns]

@yoshiserry Nein, Sie sehen, dass eine Reihe erstellt wird, die mit dem ursprünglichen Datenrahmen übereinstimmt, im Gegensatz zu den anderen Methoden, bei denen die eindeutigen Werte und ihre Häufigkeit angezeigt werden, wenn Sie dem Datenrahmen, für den Sie die Transformation verwenden können, nur die Häufigkeit hinzufügen möchten Dies. Es ist nur eine andere Technik. Sie stellen fest, dass der Datenrahmen nach dem Zurückweisen nicht reduziert wurde und keine Werte fehlen. Ich denke auch, dass Dataframes immer einen Index haben. Ich glaube nicht, dass Sie ihn loswerden, nur zurücksetzen, einen neuen zuweisen oder eine Spalte als Index verwenden können
EdChum

4
In Ihrem ersten Codebeispiel wird df wie erwartet zugewiesen, aber diese Zeile: df.groupby ('a'). Count () gibt einen leeren Datenrahmen zurück. Ist es möglich, dass diese Antwort mit Pandas 0.18.1 nicht mehr aktuell ist? Es ist auch etwas verwirrend, dass Ihr Spaltenname 'a' mit dem Wert übereinstimmt, den Sie nach 'a' suchen. Ich würde es selbst bearbeiten, aber da der Code für mich nicht funktioniert, kann ich mir meiner Änderungen nicht sicher sein.
Alex

1
@Alex Sie haben Recht, es sieht so aus, als ob dies in den neuesten Versionen nicht mehr funktioniert. Es scheint mir ein Fehler zu sein, da ich nicht verstehe, warum nicht
EdChum

1
Warum nicht df.['a'].value_counts().reset_index()statt verwenden df.groupby('a')['a'].transform('count')?
Tandem

1
@tandem, sie machen verschiedene Dinge, das Aufrufen value_countsgeneriert eine Häufigkeitszählung. Wenn Sie das Ergebnis als neue Spalte zu Ihrem ursprünglichen df hinzufügen möchten, müssen Sie es transformwie in meiner Antwort beschrieben verwenden.
EdChum

93

Wenn Sie auf alle Spalten anwenden möchten, können Sie Folgendes verwenden:

df.apply(pd.value_counts)

Dadurch wird auf jede Spalte eine spaltenbasierte Aggregationsfunktion (in diesem Fall value_counts) angewendet.


10
Dies ist die einfachste Antwort. Dies sollte oben sein.
Jeffrey Jose

4
Diese Antwort ist einfach, aber (ich glaube) die applyOperation nutzt nicht die Vorteile, die vektorisierte Numpy-Arrays als Spalten bieten. Infolgedessen kann die Leistung bei größeren Datenmengen ein Problem darstellen.
Kuanb

58
df.category.value_counts()

Diese kurze kleine Codezeile gibt Ihnen die gewünschte Ausgabe.

Wenn Ihr Spaltenname Leerzeichen enthält, können Sie diese verwenden

df['category'].value_counts()

2
Oder verwenden Sie [], wenn der Spaltenname Leerzeichen enthält. df['category 1'].value_counts()
Jacob Kalakal Joseph

19
df.apply(pd.value_counts).fillna(0)

value_counts - Gibt ein Objekt zurück, das die Anzahl der eindeutigen Werte enthält

anwenden - Häufigkeit in jeder Spalte zählen. Wenn Sie einstellen axis=1, erhalten Sie die Frequenz in jeder Zeile

fillna (0) - macht die Ausgabe ausgefallener. NaN wurde auf 0 geändert


1
Dies ist sehr leistungsfähig, wenn Vorkommen eines Werts über Spalten für dieselbe Zeile gezählt werden !!
Amc

14

In 0.18.1 groupbyzusammen mit countgibt nicht die Häufigkeit eindeutiger Werte an:

>>> df
   a
0  a
1  b
2  s
3  s
4  b
5  a
6  b

>>> df.groupby('a').count()
Empty DataFrame
Columns: []
Index: [a, b, s]

Die eindeutigen Werte und ihre Häufigkeiten können jedoch leicht bestimmt werden mit size:

>>> df.groupby('a').size()
a
a    2
b    3
s    2

Bei df.a.value_counts()sortierten Werten (in absteigender Reihenfolge, dh größter Wert zuerst) werden standardmäßig zurückgegeben.



5

Wenn Ihre Datenrahmen Werte mit dem gleichen Typ hat, können Sie auch festlegen return_counts=Truein numpy.unique () .

index, counts = np.unique(df.values,return_counts=True)

np.bincount () kann schneller sein, wenn Ihre Werte Ganzzahlen sind.


4

Ohne Bibliotheken könnten Sie dies stattdessen tun:

def to_frequency_table(data):
    frequencytable = {}
    for key in data:
        if key in frequencytable:
            frequencytable[key] += 1
        else:
            frequencytable[key] = 1
    return frequencytable

Beispiel:

to_frequency_table([1,1,1,1,2,3,4,4])
>>> {1: 4, 2: 1, 3: 1, 4: 2}

1

Sie können dies auch mit Pandas tun, indem Sie Ihre Spalten zuerst als Kategorien senden, dtype="category"z

cats = ['client', 'hotel', 'currency', 'ota', 'user_country']

df[cats] = df[cats].astype('category')

und dann anrufen describe:

df[cats].describe()

Dies gibt Ihnen eine schöne Tabelle mit Wertzählungen und ein bisschen mehr :):

    client  hotel   currency    ota user_country
count   852845  852845  852845  852845  852845
unique  2554    17477   132 14  219
top 2198    13202   USD Hades   US
freq    102562  8847    516500  242734  340992

0
n_values = data.income.value_counts()

Erste eindeutige Wertzählung

n_at_most_50k = n_values[0]

Zweite eindeutige Wertanzahl

n_greater_50k = n_values[1]

n_values

Ausgabe:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Ausgabe:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster hat bereits darauf hingewiesen. Gehen Sie für Counter. Es ist blitzschnell.

import pandas as pd
from collections import Counter
import timeit
import numpy as np

df = pd.DataFrame(np.random.randint(1, 10000, (100, 2)), columns=["NumA", "NumB"])

Timer

%timeit -n 10000 df['NumA'].value_counts()
# 10000 loops, best of 3: 715 µs per loop

%timeit -n 10000 df['NumA'].value_counts().to_dict()
# 10000 loops, best of 3: 796 µs per loop

%timeit -n 10000 Counter(df['NumA'])
# 10000 loops, best of 3: 74 µs per loop

%timeit -n 10000 df.groupby(['NumA']).count()
# 10000 loops, best of 3: 1.29 ms per loop

Prost!


0

Verwenden Sie diesen Code:

import numpy as np
np.unique(df['a'],return_counts=True)

0
your data:

|category|
cat a
cat b
cat a

Lösung:

 df['freq'] = df.groupby('category')['category'].transform('count')
 df =  df.drop_duplicates()

0

Ich glaube, dass dies für jede DataFrame-Spaltenliste gut funktionieren sollte.

def column_list(x):
    column_list_df = []
    for col_name in x.columns:
        y = col_name, len(x[col_name].unique())
        column_list_df.append(y)
return pd.DataFrame(column_list_df)

column_list_df.rename(columns={0: "Feature", 1: "Value_count"})

Die Funktion "column_list" überprüft die Spaltennamen und anschließend die Eindeutigkeit der einzelnen Spaltenwerte.


Sie können eine kurze Erklärung hinzufügen, wie Ihr Code funktioniert, um Ihre Antwort zu verbessern.
DobromirM
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.