Например, я получаю фрейм данных следующим образом:
PassengerId Survived Pclass
0 1 0 3
1 2 1 1
2 3 1 3
И после вызова df.value_counts()
я могу получить value_counts()
всех столбцов, не указывая столбец каждый раз, что может быть следующим образом:
1 1
2 1
3 1
Name: PassengerId, dtype: int64
0 1
1 2
Name: Survived, dtype: int64
3 2
1 1
Name: Survived, dtype: int64
Мне интересно, как это реализовать.
Кто-нибудь может мне помочь?
Заранее спасибо.
Я думаю, что jezrael's SeriesGroupBy.value_counts
— это именно то, что я хочу.
Есть 2 решения с DataFrame.apply
для функции применения по столбцам, но индексы выравниваются по их пересечению, поэтому добавляются NaN
s:
df1 = df.apply(pd.value_counts)
print (df1)
PassengerId Survived Pclass
0 NaN 1.0 NaN
1 1.0 2.0 1.0
2 1.0 NaN NaN
3 1.0 NaN 2.0
df1 = df.apply(pd.Series.value_counts)
print (df1)
PassengerId Survived Pclass
0 NaN 1.0 NaN
1 1.0 2.0 1.0
2 1.0 NaN NaN
3 1.0 NaN 2.0
Во избежание можно использовать SeriesGroupBy.value_counts
:
df1 = df.stack().groupby(level=1).value_counts().rename_axis(('a','b')).reset_index(name='c')
print (df1)
a b c
0 PassengerId 1 1
1 PassengerId 2 1
2 PassengerId 3 1
3 Pclass 3 2
4 Pclass 1 1
5 Survived 1 2
6 Survived 0 1
Или оригинальное решение с DataFrame.stack
:
df1 = (df.apply(pd.Series.value_counts)
.stack()
.astype(int)
.rename_axis(('a','b'))
.reset_index(name='c')
print (df1)
a b c
0 0 Survived 1
1 1 PassengerId 1
2 1 Survived 2
3 1 Pclass 1
4 2 PassengerId 1
5 3 PassengerId 1
6 3 Pclass 2
Другой альтернативой является использование melt
df.reset_index().melt('index').groupby('index').value.value_counts()
Out[608]:
index value
0 0 1
1 1
3 1
1 1 2
2 1
2 3 2
1 1
Name: value, dtype: int64
Вы можете попробовать следующий код:
d = {'PassengerId':pd.Series([1,2,3]),
'Survived':pd.Series([0,1,1]),
'Pclass':pd.Series([3,1,3])}
df=pd.DataFrame(d)
print(df)
s=[]
for i in range(df.shape[0]):
s.append(pd.Series(df.apply(pd.value_counts).values[:,i]).dropna())
print('\nvalue counts each column:')
print(s)
Выход:
PassengerId Survived Pclass
0 1 0 3
1 2 1 1
2 3 1 3
value counts each column:
[1 1.0
2 1.0
3 1.0
dtype: float64, 0 1.0
1 2.0
dtype: float64, 1 1.0
3 2.0
dtype: float64]
df.apply(pd.value_counts)
?