policzyć częstotliwość występowania wartości w kolumnie ramki danych


311

Mam zestaw danych

|category|
cat a
cat b
cat a

Chciałbym móc zwrócić coś takiego (pokazując unikalne wartości i częstotliwość)

category | freq |
cat a       2
cat b       1



Kiedy używasz „df [” category ”]. Value_counts ()”, mówi, że to int? ale zwraca nazwę kolumny jako indeks? Czy jest to obiekt ramki danych, czy w jakiś sposób łączy serię (liczby) i oryginalne unikalne wartości kolumn?
yoshiserry

@yoshiserry to jest seria Pandas type(df['category'].value_counts())i tak powie
EdChum

Zrobiłem to i byłem tym zaskoczony, ale im więcej o tym myślę, ma to sens. Po wykonaniu tej czynności wartość liczy się dla niektórych kolumn, są wiersze, które chciałbym wykluczyć. Wiem, jak usunąć kolumny, ale jak wykluczyć wiersze?
yoshiserry

Odpowiedzi:


413

Użyj groupbyi 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]

Zobacz dokumenty online: http://pandas.pydata.org/pandas-docs/stable/groupby.html

Również value_counts()jako @DSM skomentował, wiele sposobów na skórę kota tutaj

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

Out[38]:

b    3
a    2
s    2
dtype: int64

Jeśli chcesz dodać częstotliwość z powrotem do oryginalnej ramki danych, użyj przycisku, transformaby zwrócić wyrównany indeks:

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 Nie, widzisz, że tworzy serię, która jest wyrównana z oryginalną ramką danych, w przeciwieństwie do innych metod, które wyświetlają unikalne wartości i ich częstotliwość, jeśli chcesz po prostu dodać licznik częstotliwości z powrotem do ramki danych, dla której możesz użyć transformacji to. To tylko kolejna technika, zauważasz, że nie zwinął ramki danych po przypisaniu z powrotem i nie ma brakujących wartości. Myślę też, że Dataframes zawsze mają indeks. Nie sądzę, że można się go pozbyć, wystarczy go zresetować, przypisać nowy lub użyć kolumny jako indeksu
EdChum

4
W pierwszym przykładzie kodu df jest przypisywany zgodnie z oczekiwaniami, ale ten wiersz: df.groupby ('a'). Count () zwraca pustą ramkę danych. Czy to możliwe, że ta odpowiedź jest nieaktualna w przypadku pand 0.18.1? Trochę mylące jest również to, że nazwa kolumny „a” jest taka sama, jak szukana wartość „a”. Zrobiłbym to sam, ale ponieważ kod nie działa dla mnie, nie mogę być pewien moich zmian.
Alex

1
@Alex masz rację, wygląda na to, że w najnowszych wersjach to już nie działa, wydaje mi się błędem, ponieważ nie rozumiem, dlaczego nie
EdChum

1
Dlaczego nie użyć df.['a'].value_counts().reset_index()zamiast df.groupby('a')['a'].transform('count')?
tandem

1
@ tandem, robią różne rzeczy, wywołanie value_countswygeneruje licznik częstotliwości, jeśli chcesz dodać wynik z powrotem jako nową kolumnę do oryginalnego pliku df, to musisz użyć, transformjak opisano w mojej odpowiedzi.
EdChum,

93

Jeśli chcesz zastosować do wszystkich kolumn, możesz użyć:

df.apply(pd.value_counts)

Spowoduje to zastosowanie funkcji agregacji opartej na kolumnach (w tym przypadku value_counts) do każdej kolumny.


10
To najprostsza odpowiedź. To powinno być na górze.
Jeffrey Jose

4
Ta odpowiedź jest prosta, ale (jak sądzę) applyoperacja nie wykorzystuje zalet, które wektoryzowały tablice Numpy, jak zapewniają kolumny. W rezultacie wydajność może stanowić problem w przypadku większych zestawów danych.
kuanb

58
df.category.value_counts()

Ten krótki wiersz kodu daje pożądane wyniki.

Jeśli nazwa kolumny zawiera spacje, których możesz użyć

df['category'].value_counts()

2
Lub użyj [], jeśli nazwa kolumny ma spację. df['category 1'].value_counts()
Jacob Kalakal Joseph

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

value_counts - Zwraca obiekt zawierający liczbę unikalnych wartości

zastosowanie - policz częstotliwość w każdej kolumnie. Jeśli ustawisz axis=1, otrzymasz częstotliwość w każdym rzędzie

fillna (0) - spraw, aby wyjście było bardziej fantazyjne. Zmieniono NaN na 0


1
Jest to bardzo potężne, gdy liczy się wystąpienia wartości w kolumnach dla tego samego wiersza !!
amc

14

W 0.18.1 groupbyrazem z countnie podaje częstotliwości unikalnych wartości:

>>> 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]

Jednak unikalne wartości i ich częstotliwości można łatwo ustalić za pomocą size:

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

W przypadku df.a.value_counts()wartości posortowanych (w kolejności malejącej, tzn. Najpierw największej wartości) zwracane są domyślnie.



5

Jeśli twoja DataFrame ma wartości tego samego typu, możesz również ustawić return_counts=Truew numpy.unique () .

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

np.bincount () może być szybszy, jeśli twoje wartości są liczbami całkowitymi.


4

Bez bibliotek możesz to zrobić zamiast:

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

Przykład:

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

1

Możesz to również zrobić z pandami, nadając najpierw swoje kolumny jako kategorie, np. dtype="category"Np

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

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

a następnie dzwoniąc describe:

df[cats].describe()

To da ci fajną tabelę wartości i trochę więcej :):

    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()

Liczy się pierwsza unikalna wartość

n_at_most_50k = n_values[0]

Liczy się druga unikalna wartość

n_greater_50k = n_values[1]

n_values

Wynik:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Wynik:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster już to zauważył. Idź do Counter. Płonie szybko.

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"])

Timery

%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

Twoje zdrowie!



0
your data:

|category|
cat a
cat b
cat a

rozwiązanie:

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

0

Uważam, że powinno to działać poprawnie dla każdej listy kolumn DataFrame.

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"})

Funkcja „lista_kolumnowa” sprawdza nazwy kolumn, a następnie sprawdza unikalność każdej wartości kolumny.


Możesz dodać krótkie objaśnienie działania kodu, aby poprawić swoją odpowiedź.
DobromirM
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.