我有一个看起来像这样的数据框:
身份证 | f_1 | f_2 | f_3 |
---|---|---|---|
1 | 1 | 0 | 1 |
2 | 0 | 1 | 1 |
3 | 1 | 1 | 0 |
4 | 1 | 0 | 1 |
5 | 0 | 1 | 1 |
我完全不知道如何开始。而且我的原始数据帧相当大(约 1M 行),因此非常感谢快速方法。
并且我想生成一个新列
Result
来记录其中有 1 的一对 f
,即
身份证 | f_1 | f_2 | f_3 | 结果 |
---|---|---|---|---|
1 | 1 | 0 | 1 | 1_3 |
2 | 0 | 1 | 1 | 2_3 |
3 | 1 | 1 | 0 | 1_2 |
4 | 1 | 0 | 1 | 1_3 |
5 | 0 | 1 | 1 | 2_3 |
dot
/str.replace
重命名列后,您可以使用 str.removeprefix
产品:
tmp = df.drop(columns='ID')
df['Result'] = (tmp @ tmp.columns.str.replace('^f', '', regex=True)).str[1:]
# variant
df['Result'] = (tmp @ tmp.columns.str.removeprefix('f')).str[1:]
melt
)、过滤(使用 query
)和 groupby.agg
:
df['Result'] = (df.melt('ID', ignore_index=False).query('value == 1')
.groupby(level=0)['variable']
.agg(lambda x: '_'.join(x.str.extract('_(\d+)', expand=False)))
)
stack
:
s = df.drop(columns='ID').stack()
df['Result'] = (s[s==1].reset_index(-1).groupby(level=0)['level_1']
.agg(lambda x: '_'.join(x.str.extract('_(\d+)', expand=False)))
)
输出:
ID f_1 f_2 f_3 Result
0 1 1 0 1 1_3
1 2 0 1 1 2_3
2 3 1 1 0 1_2
3 4 1 0 1 1_3
4 5 0 1 1 2_3
在 20K 行上:
# dot product
2.96 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# melt + groupby.agg
965 ms ± 59.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# stack + groupby.agg
928 ms ± 43.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
在 1M 行上:
# dot product
359 ms ± 56.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# melt/stack + groupby.agg
did not run under a few minutes