我有一个数据集,它有几个行和列,但在标记为"active"的列中,我希望删除聚合并将其分离为自己的唯一计数。我还想添加一个列,给这个计数一个唯一的id。
数据
Pair gen box date active
sox black bl 2021 3
sox red re 2021 2
所需
Pair gen box date active count
sox black bl 2021 1 b101
sox black bl 2021 1 bl02
sox black bl 2021 1 bl02
sox red re 2021 1 re01
sox red re 2021 1 re02
"active"列现在分别有3行和2行不同的行,以及一个不同的计数ID(基于"box"列(,而不是一个聚合。
执行
一位SO协助解决了类似的困境,我正在采取这种方法:
# Melt Table Into New Form
df = df.melt(col_level=0, value_name='count', var_name='bl')
# Repeat Based on Count
df = df.reindex(df.index.repeat(df['count']))
# Set Count To 1
df['count'] = 1
# Add Suffix to Each ID
df['ID'] = df['ID'] + (
(df.groupby('ID').cumcount() + 1)
.astype(str)
.str.zfill(2)
)
然而,这是有效的,我无法保留其他列以及设置单独的var名称,例如:
bl01
bl02
re01
re02
欢迎任何建议
您不需要melt
来解决此问题,可以使用以下reindex
和repeat
。请记住,对于count
列,我意识到如果每个组都有一个大小>10
,例如,当您真正想要bl10
时,它会显示为bl010
。尽管分组大小小于10并且分组大小>10,不清楚想要的输出是什么:
df = df.reindex(df.index.repeat(df['active'])).assign(active=1)
df['count'] = df['box'] + '0' + (df.groupby(['Pair', 'gen', 'box']).cumcount() + 1).astype(str)
df
Out[1]:
Pair gen box date active count
0 sox black bl 2021 1 bl01
0 sox black bl 2021 1 bl02
0 sox black bl 2021 1 bl03
1 sox red re 2021 1 re01
1 sox red re 2021 1 re02
另一个方法是沿着轴的concat,然后使用cumcount创建计数列。
dfs = pd.concat([pd.concat([y.assign(active=1,)] * act)
for (idx,act),y in df.groupby([df.index, df['active']])])
dfs['count'] = dfs['box'] + (dfs.groupby('box').cumcount() + 1).astype(str).str.zfill(2)
print(dfs)
Pair gen box date active count
0 sox black bl 2021 1 bl01
0 sox black bl 2021 1 bl02
0 sox black bl 2021 1 bl03
1 sox red re 2021 1 re01
1 sox red re 2021 1 re02