如何为 pandas 数据框列生成权重?
How to generate weights for pandas dataframe column?
我有以下 pandas DataFrame df
:
col1 col2
0.2 0
0.1 1
0.6 1
0.3 1
0.5 0
0.2 0
0.3 1
0.5 1
0.7 1
0.1 1
我需要根据 col2
值生成一个新列 col3
。逻辑应该是这样的:
1
的每批顺序值的权重应介于 1 和 0 之间。
这是预期的结果:
col1 col2 col3
0.2 0 0.0
0.1 1 1.0
0.6 1 0.66
0.3 1 0.33
0.5 0 0.0
0.2 0 0.0
0.3 1 1.0
0.5 1 0.75
0.7 1 0.50
0.1 1 0.25
这是一种方法:
groups = df['col2'].eq(0).cumsum()
g = df['col2'].eq(1).groupby(groups)
df['col3'] = g.cumsum().div(g.transform('sum')).fillna(0)
df.loc[df['col2']==1, 'col3'] = df['col3'].groupby(groups).apply(lambda x: x.iloc[1:][::-1]).to_numpy()
输出:
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
使用:
weights = lambda x:1 - (x / x.size).cumsum().shift(fill_value=0)
df['col3'] = df.groupby(df['col2'].eq(0).cumsum().mask(df['col2'].eq(0)))['col2'] \
.apply(weights).reindex(df.index, fill_value=0)
print(df)
# Output
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
如何分组?
>>> df.assign(group=df['col2'].eq(0).cumsum().mask(df['col2'].eq(0)))
col1 col2 group
0 0.2 0 NaN
1 0.1 1 1.0 # First group, 3 consecutive 1
2 0.6 1 1.0
3 0.3 1 1.0
4 0.5 0 NaN
5 0.2 0 NaN
6 0.3 1 3.0 # Second group, 4 consecutive 1
7 0.5 1 3.0
8 0.7 1 3.0
9 0.1 1 3.0
快速而肮脏
mask = df.col2.ne(1)
grps = mask.cumsum().mask(mask, 0)
gb = grps.groupby(grps)
df.assign(col3=(1 - gb.cumcount() / gb.transform('size')).mask(mask, 0))
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
或者鲜为人知的 groupby 管道也是如此
mask = df.col2.ne(1)
grps = mask.cumsum().mask(mask, 0)
func = lambda g: g.cumcount() / g.transform('size')
df.assign(col3=(1 - grps.groupby(grps).pipe(func).mask(mask, 0)))
我有以下 pandas DataFrame df
:
col1 col2
0.2 0
0.1 1
0.6 1
0.3 1
0.5 0
0.2 0
0.3 1
0.5 1
0.7 1
0.1 1
我需要根据 col2
值生成一个新列 col3
。逻辑应该是这样的:
1
的每批顺序值的权重应介于 1 和 0 之间。
这是预期的结果:
col1 col2 col3
0.2 0 0.0
0.1 1 1.0
0.6 1 0.66
0.3 1 0.33
0.5 0 0.0
0.2 0 0.0
0.3 1 1.0
0.5 1 0.75
0.7 1 0.50
0.1 1 0.25
这是一种方法:
groups = df['col2'].eq(0).cumsum()
g = df['col2'].eq(1).groupby(groups)
df['col3'] = g.cumsum().div(g.transform('sum')).fillna(0)
df.loc[df['col2']==1, 'col3'] = df['col3'].groupby(groups).apply(lambda x: x.iloc[1:][::-1]).to_numpy()
输出:
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
使用:
weights = lambda x:1 - (x / x.size).cumsum().shift(fill_value=0)
df['col3'] = df.groupby(df['col2'].eq(0).cumsum().mask(df['col2'].eq(0)))['col2'] \
.apply(weights).reindex(df.index, fill_value=0)
print(df)
# Output
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
如何分组?
>>> df.assign(group=df['col2'].eq(0).cumsum().mask(df['col2'].eq(0)))
col1 col2 group
0 0.2 0 NaN
1 0.1 1 1.0 # First group, 3 consecutive 1
2 0.6 1 1.0
3 0.3 1 1.0
4 0.5 0 NaN
5 0.2 0 NaN
6 0.3 1 3.0 # Second group, 4 consecutive 1
7 0.5 1 3.0
8 0.7 1 3.0
9 0.1 1 3.0
快速而肮脏
mask = df.col2.ne(1)
grps = mask.cumsum().mask(mask, 0)
gb = grps.groupby(grps)
df.assign(col3=(1 - gb.cumcount() / gb.transform('size')).mask(mask, 0))
col1 col2 col3
0 0.2 0 0.000000
1 0.1 1 1.000000
2 0.6 1 0.666667
3 0.3 1 0.333333
4 0.5 0 0.000000
5 0.2 0 0.000000
6 0.3 1 1.000000
7 0.5 1 0.750000
8 0.7 1 0.500000
9 0.1 1 0.250000
或者鲜为人知的 groupby 管道也是如此
mask = df.col2.ne(1)
grps = mask.cumsum().mask(mask, 0)
func = lambda g: g.cumcount() / g.transform('size')
df.assign(col3=(1 - grps.groupby(grps).pipe(func).mask(mask, 0)))