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
yoshiserry
źródło
1
Spróbujcollections.Counter
metatoaster
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]
EdChum
źródło
@ 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.

Arran Cudbard-Bell
źródło
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()
Satyajit Dhawale
źródło
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

Roman Kazakow
źródło
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.

Vidhya G.
źródło
5

Korzystanie ze zrozumienia listy i wartości_liczb dla wielu kolumn w pliku df

[my_series[c].value_counts() for c in list(my_series.select_dtypes(include=['O']).columns)]

https://stackoverflow.com/a/28192263/786326

Shankar ARUL - jupyterdata.com
źródło
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.

użytkownik666
źródło
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}
Timz95
źródło
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
Tsando
źródło
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)
RAHUL KUMAR
źródło
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!

dragonfire_007
źródło
0

Użyj tego kodu:

import numpy as np
np.unique(df['a'],return_counts=True)
Harshit Oberoi
źródło
0
your data:

|category|
cat a
cat b
cat a

rozwiązanie:

 df['freq'] = df.groupby('category')['category'].transform('count')
 df =  df.drop_duplicates()
Rahul Jain
źródło
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.

djoguns
źródło
Możesz dodać krótkie objaśnienie działania kodu, aby poprawić swoją odpowiedź.
DobromirM