Ответ 1
Просто позвоните 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
Учитывая Pandas DataFrame, который имеет несколько столбцов с категориальными значениями (0 или 1), можно ли удобно получить значение_количество для каждого столбца одновременно?
Например, предположим, что я генерирую 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)
Но должен быть более простой способ, например, укладка, поворот или группировка?
Просто позвоните 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
На самом деле существует довольно интересный и продвинутый способ решения этой проблемы с помощью 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
Или в одной строке, которая расширяет имена столбцов до имен параметров с помощью **
(это продвинуто)
pd.crosstab(**df.melt(var_name='columns', value_name='index'))
Кроме того, value_counts
теперь является функцией верхнего уровня. Таким образом, вы можете упростить текущий выбранный ответ на следующее:
df.apply(pd.value_counts)