使用 unstack 查找事件和非事件的计数和百分比
Finding both count and percentage for event and non-events using unstack
我有一个如下所示的数据框
import numpy as np
import pandas as pd
np.random.seed(100)
from feature_engine.encoding import OrdinalEncoder
df = pd.DataFrame({'grade': np.random.choice(list('ABCD'),size=(20)),
'dash': np.random.choice(list('PQRS'),size=(20)),
'dumeel': np.random.choice(list('QWER'),size=(20)),
'dumma': np.random.choice((1234),size=(20)),
'target': np.random.choice([0,1],size=(20))
})
我想执行以下操作
a) 事件率 - 为每个输入分类列中的每个唯一值计算 1(来自目标列)的出现百分比
b) 非事件率 - 计算每个输入分类列中每个唯一值的 0 出现百分比(来自目标列)
c) 事件数 - 计算每个输入分类列中每个唯一值的 1(来自目标列)的记录数
d) 非事件数 - 计算每个输入分类列中每个唯一值的 0(来自目标列)的记录数
在 Shubham 的帮助下,我能够使用以下代码计算百分比
cols = df.select_dtypes('object')
df_out = (
df.melt('target', cols)
.groupby(['variable', 'target'])['value']
.value_counts(normalize=True)
.unstack(1, fill_value=0)
)
但是现在,除了 %,我还想获取分类值中每个唯一值的记录数或记录数
我希望我的输出如下所示
我为您提供了一个工作示例。在尝试使用 aggregate method 之后,我意识到这样做是最简单的:
import numpy as np
import pandas as pd
df = pd.DataFrame({
'grade': np.random.choice(list('ABCD'), size=(20)),
'dash': np.random.choice(list('PQRS'), size=(20)),
'dumeel': np.random.choice(list('QWER'), size=(20)),
'dumma': np.random.choice((1234), size=(20)),
'target': np.random.choice([0, 1], size=(20))
})
cols = df.select_dtypes('object')
df_out = df.melt('target', cols)
df_out.target = pd.Categorical(df_out.target, [0, 1]) # This must be made sure
df_out.value = pd.Categorical(df_out.value, list('ABCDPQRSWE')) # This must be made sure
df_out = pd.concat(
[df_out.groupby(['variable', 'target']).value_counts(normalize=flag).unstack('target')
for flag in [True, False]], axis=1, keys=['%-event', '#-event'])
正如我在代码中提到的那样,要使它起作用,适当的列是分类的是必要的。
之后您可能想重命名列 MultiIndex
df_out.columns = ['%-no_event', '%-event', '#-no_event', '#-event']
但请注意顺序!
结果
这是一种方法:
- Select 分类列 (
cols
)
Melt
以 target
作为 id 变量和 cols
作为值变量的数据框
- 使用
groupby
+ value_counts
创建频率 table (counts
)
- 标准化
counts
table 沿列轴创建 (counts_norm
)
- 连接
counts
和 counts_norm
- 使用堆栈重塑数据帧,取消堆栈
cols = df.select_dtypes('object')
counts = (
df.melt('target', cols)
.groupby(['variable', 'target'])['value']
.value_counts().unstack()
)
counts_norm = counts.div(counts.sum(1), axis=0)
df_out = pd.concat([counts, counts_norm], keys=['N', '%_N'])\
.stack().unstack([0, 2], fill_value=0)
print(df_out)
N %_N
target 0 1 0 1
variable value
dash P 4.0 3.0 0.4 0.3
Q 2.0 3.0 0.2 0.3
R 2.0 1.0 0.2 0.1
S 2.0 3.0 0.2 0.3
dumeel E 2.0 2.0 0.2 0.2
Q 1.0 0.0 0.1 0.0
R 4.0 6.0 0.4 0.6
W 3.0 2.0 0.3 0.2
grade A 4.0 2.0 0.4 0.2
B 0.0 2.0 0.0 0.2
C 4.0 3.0 0.4 0.3
D 2.0 3.0 0.2 0.3
我有一个如下所示的数据框
import numpy as np
import pandas as pd
np.random.seed(100)
from feature_engine.encoding import OrdinalEncoder
df = pd.DataFrame({'grade': np.random.choice(list('ABCD'),size=(20)),
'dash': np.random.choice(list('PQRS'),size=(20)),
'dumeel': np.random.choice(list('QWER'),size=(20)),
'dumma': np.random.choice((1234),size=(20)),
'target': np.random.choice([0,1],size=(20))
})
我想执行以下操作
a) 事件率 - 为每个输入分类列中的每个唯一值计算 1(来自目标列)的出现百分比
b) 非事件率 - 计算每个输入分类列中每个唯一值的 0 出现百分比(来自目标列)
c) 事件数 - 计算每个输入分类列中每个唯一值的 1(来自目标列)的记录数
d) 非事件数 - 计算每个输入分类列中每个唯一值的 0(来自目标列)的记录数
在 Shubham 的帮助下,我能够使用以下代码计算百分比
cols = df.select_dtypes('object')
df_out = (
df.melt('target', cols)
.groupby(['variable', 'target'])['value']
.value_counts(normalize=True)
.unstack(1, fill_value=0)
)
但是现在,除了 %,我还想获取分类值中每个唯一值的记录数或记录数
我希望我的输出如下所示
我为您提供了一个工作示例。在尝试使用 aggregate method 之后,我意识到这样做是最简单的:
import numpy as np
import pandas as pd
df = pd.DataFrame({
'grade': np.random.choice(list('ABCD'), size=(20)),
'dash': np.random.choice(list('PQRS'), size=(20)),
'dumeel': np.random.choice(list('QWER'), size=(20)),
'dumma': np.random.choice((1234), size=(20)),
'target': np.random.choice([0, 1], size=(20))
})
cols = df.select_dtypes('object')
df_out = df.melt('target', cols)
df_out.target = pd.Categorical(df_out.target, [0, 1]) # This must be made sure
df_out.value = pd.Categorical(df_out.value, list('ABCDPQRSWE')) # This must be made sure
df_out = pd.concat(
[df_out.groupby(['variable', 'target']).value_counts(normalize=flag).unstack('target')
for flag in [True, False]], axis=1, keys=['%-event', '#-event'])
正如我在代码中提到的那样,要使它起作用,适当的列是分类的是必要的。
之后您可能想重命名列 MultiIndex
df_out.columns = ['%-no_event', '%-event', '#-no_event', '#-event']
但请注意顺序!
结果
这是一种方法:
- Select 分类列 (
cols
) Melt
以target
作为 id 变量和cols
作为值变量的数据框- 使用
groupby
+value_counts
创建频率 table ( - 标准化
counts
table 沿列轴创建 (counts_norm
) - 连接
counts
和counts_norm
- 使用堆栈重塑数据帧,取消堆栈
counts
)
cols = df.select_dtypes('object')
counts = (
df.melt('target', cols)
.groupby(['variable', 'target'])['value']
.value_counts().unstack()
)
counts_norm = counts.div(counts.sum(1), axis=0)
df_out = pd.concat([counts, counts_norm], keys=['N', '%_N'])\
.stack().unstack([0, 2], fill_value=0)
print(df_out)
N %_N
target 0 1 0 1
variable value
dash P 4.0 3.0 0.4 0.3
Q 2.0 3.0 0.2 0.3
R 2.0 1.0 0.2 0.1
S 2.0 3.0 0.2 0.3
dumeel E 2.0 2.0 0.2 0.2
Q 1.0 0.0 0.1 0.0
R 4.0 6.0 0.4 0.6
W 3.0 2.0 0.3 0.2
grade A 4.0 2.0 0.4 0.2
B 0.0 2.0 0.0 0.2
C 4.0 3.0 0.4 0.3
D 2.0 3.0 0.2 0.3