使用两个 groupby-ed 列合并多个列 pandas
Binning multiple columns using two groupby-ed columns pandas
我有一个 raw table 如下所示:
Object
state
duration_hours
interval_hours
A
1
0.06
0
A
1
0.87
34
A
1
1.5
80
A
2
18
0
B
1
7
0
C
1
0.3
0
C
2
3
0
C
2
4
12
表架构:
- 对象:汽车对象
- 状态:是计划内维护还是计划外维护(1- 计划内,2- 非计划内)
- duration_hours: 计划或计划外维护用了多长时间
- interval_hours:第一次维护和下次维护相差多长时间。(每个状态的对象的第一次间隔将始终为0)
问题
我怎样才能:
- 为 duration_hours 和 interval_hours
每个 对象和状态创建容器
- 计算样本和落入容器的概率每个对象和状态。
预期输出:
输出解释 table:
bin 的大小、最小值、最大值是可配置的。
每个对象都有状态、分箱、数据样本和概率。
对于每个状态,我们有由duration_hours和interval_hours.
组成的bin
示例:对于对象 A,状态 1,我们有:
一个。 duration_hours 的两个箱子和 interval_hours 的两个箱子。
b。由于 [0,1) 之间有 2 个数据样本 duration_hours,我们有 2 个数据样本和 (2/3)= 0.67 概率,同样对于间隔小时,我们有 2 个数据样本 [-1,50 ), 我们有 2 data_sample 输出和 prob = 2/3.
真诚感谢任何帮助。
我不确定这是否正是您想要的,但也许您可以使用它的一部分。
如果您的基础数据框命名为 df
,您可以开始使用 pd.cut()
对列 duration_hours
和 interval_hours
:
进行分箱
bins = range(int(df.duration_hours.max()) + 2)
df["dur"] = pd.cut(df.duration_hours, bins, right=False)
bins = range(0, int(df.interval_hours.max()) + 51, 50)
df["int"] = pd.cut(df.interval_hours, bins, right=False)
然后.melt()
将结果放入一个新的dataframe中df_res
df_res = df.melt(
id_vars=["Object", "state"], value_vars=["dur", "int"],
value_name="Bins", var_name="Variable",
)
and groupby()
and .sum()
覆盖其中的大部分以获得 Sample
列
group = ["Object", "state", "Variable", "Bins"]
df_res = (
df_res[group].assign(Sample=1).groupby(group, observed=True).sum()
)
并使用它来构建 Prob
列(通过 .groupby()
-transform().sum()
在前三个索引级别上):
df_res["Prob"] = (
df_res.Sample / df_res.groupby(level=[0, 1, 2]).Sample.transform('sum')
)
结果
df =
Object state duration_hours interval_hours
0 A 1 0.06 0
1 A 1 0.87 34
2 A 1 1.50 80
3 A 2 18.00 0
4 B 1 7.00 0
5 C 1 0.30 0
6 C 2 3.00 0
7 C 2 4.00 12
是
Sample Prob
Object state Variable Bins
A 1 dur [0, 1) 2 0.666667
[1, 2) 1 0.333333
int [0, 50) 2 0.666667
[50, 100) 1 0.333333
2 dur [18, 19) 1 1.000000
int [0, 50) 1 1.000000
B 1 dur [7, 8) 1 1.000000
int [0, 50) 1 1.000000
C 1 dur [0, 1) 1 1.000000
int [0, 50) 1 1.000000
2 dur [3, 4) 1 0.500000
[4, 5) 1 0.500000
int [0, 50) 2 1.000000
我有一个 raw table 如下所示:
Object | state | duration_hours | interval_hours |
---|---|---|---|
A | 1 | 0.06 | 0 |
A | 1 | 0.87 | 34 |
A | 1 | 1.5 | 80 |
A | 2 | 18 | 0 |
B | 1 | 7 | 0 |
C | 1 | 0.3 | 0 |
C | 2 | 3 | 0 |
C | 2 | 4 | 12 |
表架构:
- 对象:汽车对象
- 状态:是计划内维护还是计划外维护(1- 计划内,2- 非计划内)
- duration_hours: 计划或计划外维护用了多长时间
- interval_hours:第一次维护和下次维护相差多长时间。(每个状态的对象的第一次间隔将始终为0)
问题
我怎样才能:
- 为 duration_hours 和 interval_hours 每个 对象和状态创建容器
- 计算样本和落入容器的概率每个对象和状态。
预期输出:
bin 的大小、最小值、最大值是可配置的。
每个对象都有状态、分箱、数据样本和概率。
对于每个状态,我们有由duration_hours和interval_hours.
组成的bin示例:对于对象 A,状态 1,我们有:
一个。 duration_hours 的两个箱子和 interval_hours 的两个箱子。
b。由于 [0,1) 之间有 2 个数据样本 duration_hours,我们有 2 个数据样本和 (2/3)= 0.67 概率,同样对于间隔小时,我们有 2 个数据样本 [-1,50 ), 我们有 2 data_sample 输出和 prob = 2/3.
真诚感谢任何帮助。
我不确定这是否正是您想要的,但也许您可以使用它的一部分。
如果您的基础数据框命名为 df
,您可以开始使用 pd.cut()
对列 duration_hours
和 interval_hours
:
bins = range(int(df.duration_hours.max()) + 2)
df["dur"] = pd.cut(df.duration_hours, bins, right=False)
bins = range(0, int(df.interval_hours.max()) + 51, 50)
df["int"] = pd.cut(df.interval_hours, bins, right=False)
然后.melt()
将结果放入一个新的dataframe中df_res
df_res = df.melt(
id_vars=["Object", "state"], value_vars=["dur", "int"],
value_name="Bins", var_name="Variable",
)
and groupby()
and .sum()
覆盖其中的大部分以获得 Sample
列
group = ["Object", "state", "Variable", "Bins"]
df_res = (
df_res[group].assign(Sample=1).groupby(group, observed=True).sum()
)
并使用它来构建 Prob
列(通过 .groupby()
-transform().sum()
在前三个索引级别上):
df_res["Prob"] = (
df_res.Sample / df_res.groupby(level=[0, 1, 2]).Sample.transform('sum')
)
结果
df =
Object state duration_hours interval_hours
0 A 1 0.06 0
1 A 1 0.87 34
2 A 1 1.50 80
3 A 2 18.00 0
4 B 1 7.00 0
5 C 1 0.30 0
6 C 2 3.00 0
7 C 2 4.00 12
是
Sample Prob
Object state Variable Bins
A 1 dur [0, 1) 2 0.666667
[1, 2) 1 0.333333
int [0, 50) 2 0.666667
[50, 100) 1 0.333333
2 dur [18, 19) 1 1.000000
int [0, 50) 1 1.000000
B 1 dur [7, 8) 1 1.000000
int [0, 50) 1 1.000000
C 1 dur [0, 1) 1 1.000000
int [0, 50) 1 1.000000
2 dur [3, 4) 1 0.500000
[4, 5) 1 0.500000
int [0, 50) 2 1.000000