підраховують частоту, яка виникає у стовпчику фрейму даних


312

У мене є набір даних

|category|
cat a
cat b
cat a

Мені б хотілося повернути щось на зразок (показуючи унікальні значення та частоту)

category | freq |
cat a       2
cat b       1


94
DSM

При використанні "df [" категорія "]. Value_counts ()" вона каже, що це int? але воно повертає ім'я стовпця як індекс? Це об'єкт фрейму даних або це якимось чином поєднує ряд (підраховує) та початкові унікальні значення стовпців?
йошизеррі

@yoshiserry - це серія Pandas, type(df['category'].value_counts())і це скаже так
EdChum

Я це зробив, і мене це здивувало, але є сенс, чим більше я думаю про це. Після цього значення нараховується на деяких колонках, є рядки, які я хотів би виключити. Я знаю, як видалити стовпці, але як я виключаю рядки?
йошизеррі

Відповіді:


413

Використання groupbyта 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]

Дивіться онлайн-документи: http://pandas.pydata.org/pandas-docs/stable/groupby.html

Крім того, value_counts()як @DSM прокоментував, тут існує багато способів зняти кішку

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

Out[38]:

b    3
a    2
s    2
dtype: int64

Якщо ви хочете додати частоту назад до початкового фрейму даних, використовуйте transformдля повернення вирівняного індексу:

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 Ні, те, що ви бачите, це те, що він створює серію, яка вирівнюється з оригінальним фреймом даних, на відміну від інших методів, які відображають унікальні значення та їх частоту, якщо ви хочете просто додати числовий частоту назад до фрейму даних, який можна використовувати для перетворення для це. Це просто інша техніка, ви помічаєте, що вона не згорнула рамку даних після присвоєння назад і відсутні відсутні значення. Також я думаю, що у Dataframes завжди є індекс, я не думаю, що ви можете його позбутися, лише скиньте його, призначте новий або використовуйте стовпчик як індекс
EdChum

4
У вашому першому прикладі коду df призначається як очікувалося, але цей рядок: df.groupby ('a'). Count () повертає порожній кадр даних. Чи можливо ця відповідь застаріла з пандами 0.18.1? Крім того, трохи заплутано те, що назва вашого стовпця "a" збігається зі значенням, яке ви шукаєте "a". Я б сам це редагував, але оскільки код не працює для мене, я не можу бути впевнений у своїх змінах.
Алекс

1
@ Алекс ти прав, схоже, що в останніх версіях це більше не працює, мені здається помилкою, тому що я не розумію, чому ні
EdChum

1
Чому б не використовувати df.['a'].value_counts().reset_index()замість df.groupby('a')['a'].transform('count')?
тандем

1
@tandem, вони роблять різні речі, при виклику value_countsбуде генеруватися частота підрахунків, якщо ви хочете додати результат назад як новий стовпець проти оригінального df, тоді вам доведеться використовувати transformяк детальніше в моїй відповіді.
EdChum

93

Якщо ви хочете застосувати всі стовпці, ви можете використовувати:

df.apply(pd.value_counts)

Це застосує функцію агрегування на основі стовпців (у цьому випадку value_counts) до кожного з стовпців.


10
Це найпростіша відповідь. Це має бути вгорі.
Джефрі Хосе

4
Ця відповідь проста, але (я вважаю), що applyоперація не використовує переваги, які надає векторний масив Numpy у стовпцях. Як результат, продуктивність може стати проблемою для великих наборів даних.
kuanb

58
df.category.value_counts()

Цей короткий невеликий рядок коду дасть вам потрібний вихід.

Якщо в назві стовпця є пробіли, які ви можете використовувати

df['category'].value_counts()

2
Або використовуйте [], якщо в назві стовпця є пробіл. df['category 1'].value_counts()
Яків Калакал Йосиф

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

value_counts - Повертає об'єкт, що містить кількість унікальних значень

застосовувати - рахувати частоту в кожному стовпці. Якщо ви встановите axis=1, ви отримуєте частоту в кожному рядку

fillna (0) - зробити вихід більш фантазійним. Змінено NaN на 0


1
Це дуже потужно, коли підраховують події значення у стовпцях для одного рядка !!
amc

14

У 0.18.1 groupbyразом з countне дає частоти унікальних значень:

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

Однак унікальні значення та їх частоти легко визначаються за допомогою size:

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

З df.a.value_counts()відсортованими значеннями (у порядку зменшення, тобто спочатку найбільше значення) повертаються за замовчуванням.



5

Якщо у вашому DataFrame є значення одного типу, ви також можете встановити return_counts=Trueв numpy.unique () .

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

np.bincount () може бути швидшим, якщо ваші значення - цілі числа.


4

Без бібліотек ви можете зробити це замість цього:

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

Приклад:

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

1

Ви також можете це зробити з пандами, спочатку транслюючи свої стовпці як категорії, наприклад, dtype="category"наприклад

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

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

а потім дзвонить describe:

df[cats].describe()

Це дасть вам хорошу таблицю підрахунків вартості та трохи більше :):

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

Перше унікальне значення

n_at_most_50k = n_values[0]

Другий унікальний підрахунок значення

n_greater_50k = n_values[1]

n_values

Вихід:

<=50K    34014
>50K     11208

Name: income, dtype: int64

Вихід:

n_greater_50k,n_at_most_50k:-
(11208, 34014)

0

@metatoaster вже вказав на цьому. Ідіть на Counter. Це швидко палає.

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

Таймери

%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

Ура!



0
your data:

|category|
cat a
cat b
cat a

рішення:

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

0

Я вважаю, що це повинно працювати добре для будь-якого списку стовпців 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"})

Функція "column_list" перевіряє назви стовпців, а потім перевіряє унікальність значень кожного стовпця.


Ви можете додати коротке пояснення того, як працює ваш код, щоб покращити відповідь.
ДобромірМ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.