web-dev-qa-db-ja.com

Pandas DataFrame?で複数の列の値のカウントを一度に取得するには?

カテゴリ値(0または1)を持つ複数の列を持つPandas DataFrameが与えられた場合、すべての列のvalue_countsを同時に便利に取得できますか?

たとえば、次のようにDataFrameを生成するとします。

import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd'))

次のようなDataFrameを取得できます。

   a  b  c  d
0  0  1  1  0
1  1  1  1  1
2  1  1  1  0
3  0  1  0  0
4  0  0  0  1
5  0  1  1  0
6  0  1  1  1
7  1  0  1  0
8  1  0  1  1
9  0  1  1  0

すべての列の値のカウントを便利に取得し、次のものを便利に取得するにはどうすればよいですか?

   a  b  c  d
0  6  3  2  6
1  4  7  8  4

私の現在のソリューションは次のとおりです。

pieces = []
for col in df.columns:
    tmp_series = df[col].value_counts()
    tmp_series.name = col
    pieces.append(tmp_series)
df_value_counts = pd.concat(pieces, axis=1)

しかし、スタッキング、ピボット、またはグループバイなど、より簡単な方法が必要ですか?

37
Xin

apply を呼び出して、 pd.Series.value_counts

In [212]:
df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd'))
df.apply(pd.Series.value_counts)
Out[212]:
   a  b  c  d
0  4  6  4  3
1  6  4  6  7
65
EdChum

crosstab および melt を使用して、この問題を実行するかなり興味深い高度な方法が実際にあります。

df = pd.DataFrame({'a': ['table', 'chair', 'chair', 'lamp', 'bed'],
                   'b': ['lamp', 'candle', 'chair', 'lamp', 'bed'],
                   'c': ['mirror', 'mirror', 'mirror', 'mirror', 'mirror']})

df

       a       b       c
0  table    lamp  mirror
1  chair  candle  mirror
2  chair   chair  mirror
3   lamp    lamp  mirror
4    bed     bed  mirror

最初にDataFrameを溶かすことができます

df1 = df.melt()
df1

   columns   index
0        a   table
1        a   chair
2        a   chair
3        a    lamp
4        a     bed
5        b    lamp
6        b  candle
7        b   chair
8        b    lamp
9        b     bed
10       c  mirror
11       c  mirror
12       c  mirror
13       c  mirror
14       c  mirror

次に、クロス集計関数を使用して、各列の値をカウントします。これにより、現在選択されている回答には当てはまらないintとしてデータ型が保持されます。

pd.crosstab(index=df['index'], columns=df['columns'])

columns  a  b  c
index           
bed      1  1  0
candle   0  1  0
chair    2  1  0
lamp     1  2  0
mirror   0  0  5
table    1  0  0

または、1行で、列名を**でパラメーター名に展開します(これは高度です)

pd.crosstab(**df.melt(var_name='columns', value_name='index'))

また、value_countsはトップレベルの関数になりました。そのため、現在選択されている次の回答を簡素化できます。

df.apply(pd.value_counts)
18
Ted Petrou