データフレーム列で値が発生する頻度を数える


313

データセットがあります

|category|
cat a
cat b
cat a

(一意の値と頻度を示す)などを返すことができるようにしたい

category | freq |
cat a       2
cat b       1


94
お探しdf["category"].value_counts()ですか?
DSM

"df [" category "]。value_counts()"を使用すると、intと表示されますか?しかし、それはインデックスとして列名を返しますか?それはデータフレームオブジェクトですか、それともシリーズ(カウント)と元の一意の列値を何らかの形で組み合わせていますか?
yoshiserry 2014年

@yoshiserryそれはパンダのシリーズでありtype(df['category'].value_counts())、そう言うでしょう
EdChum

私はそうしました、そして私はそれに驚いていましたが、私はそれについて考えるほど理にかなっています。これを行った後、いくつかの列で値が重要になります。除外したい行があります。列を削除する方法は知っていますが、行を除外するにはどうすればよいですか?
yoshiserry 2014年

回答:


414

使用するgroupbycount

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いいえ、表示されているのは、一意の値とその頻度を表示する他の方法とは異なり、元のデータフレームに合わせて系列を作成することです。変換に使用できるデータフレームに頻度カウントを追加するだけの場合、この。これはもう1つの手法であり、割り当て直した後でデータフレームが縮小されておらず、欠損値がないことがわかります。また、データフレームには常にインデックスがあると思います。それを取り除くことはできません。リセットするか、新しいインデックスを割り当てるか、列をインデックスとして使用します
EdChum

4
最初のコード例では、dfは期待どおりに割り当てられますが、次の行:df.groupby( 'a')。count()は空のデータフレームを返します。この回答がパンダ0.18.1では古くなっている可能性はありますか?また、列名「a」が「a」を検索している値と同じであると少し混乱します。私は自分で編集しますが、コードが機能しないため、編集内容を確認できません。
Alex

1
@Alex正解です。最新バージョンでは動作しないようです。なぜかわからないため、私にはバグのようです
EdChum

1
df.['a'].value_counts().reset_index()代わりに使用しないのはなぜdf.groupby('a')['a'].transform('count')ですか?
タンデム

1
@タンデム、彼らはさまざまなことをします、呼び出しvalue_countsは頻度カウントを生成します、もしあなたがあなたの元のdfに対して新しい列として結果を追加したいなら、あなたtransformは私の答えで詳述されているように使わなければなりません。
EdChum

93

すべての列に適用したい場合は、以下を使用できます。

df.apply(pd.value_counts)

これにより、列ベースの集計関数(この場合はvalue_counts)が各列に適用されます。


10
これが最も簡単な答えです。これが一番上になるはずです。
Jeffrey Jose

4
この答えは単純ですが(私は信じています)、apply操作は列が提供するようにNumpy配列をベクトル化する利点を活用していません。その結果、大規模なデータセットではパフォーマンスが問題になる可能性があります。
kuanb 2017

58
df.category.value_counts()

この短いコード行により、必要な出力が得られます。

列名にスペースが含まれている場合、使用できます

df['category'].value_counts()

2
または、列名にスペースがある場合は[]を使用します。df['category 1'].value_counts()
Jacob Kalakal Joseph

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

value_counts-一意の値の数を含むオブジェクトを返します

apply-すべての列の頻度をカウントします。を設定すると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=Truenumpy.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]

2番目の固有値カウント

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"は列名をチェックしてから、各列値の一意性をチェックします。


答えを改善するためにコードがどのように機能するかについての簡単な説明を追加できます。
DobromirM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.