我正在使用python中的数据抑制脚本,其中我需要1)抑制小值(1到5之间)和2)确保在最小的聚合级别上至少有2个值被抑制。我已经完成了第一步,用-1替换小值(稍后我将重新编码为" ")。我创建了一个新的助手列,用于计算每行有多少个被抑制的值('sup_cnt')。结果是这样的:
Subgroup cat1 cat2 cat3 sup_cnt
Group1 0 -1 0 1
Group2 -1 22 6 1
Group3 -1 14 -1 2
Group4 -1 -1 0 2
data = {'group':['group1','group2','group3','group4'],'cat1':[0,-1,-1,-1],'cat2':[-1,22,14,-1],'cat3':[0,0,-1,0],'sup_cnt':[1,1,2,3]}
df = pd.DataFrame(data)
因此,对于Group1和Group2,它们只有一个值被抑制,我想要第二个值——最低的(包括0)——用-1替换。在Group1中,其中一个0将被替换;在第2组中,6将被取代。所以结果是这样的:
Subgroup cat1 cat2 cat3 sup_cnt
Group1 -1 -1 0 1
Group2 -1 22 -1 1
Group3 -1 14 -1 2
Group4 -1 -1 0 2
如果有多个列具有相同的最低值(如Group1,它有两个零),我只希望替换其中一个(与哪个无关)。
最初是在R中开始的,然后切换到python/pandas(但我对pandas很陌生)。我的想法是编写一个函数,将cat值作为参数,确定其中的最小非负整数,循环遍历一行中的数据列并替换该行中最小值的第一个实例,然后中断。但我不确定这是否是正确的方法(或者确切地说如何执行)。什么好主意吗?
我希望我没理解错你的问题:
def fn(x):
cols = x.filter(regex=r"^cat")
x = cols[cols >= 0].sort_values()[: 2 - x["sup_cnt"]]
df.loc[x.name, x.index] = -1
df[df.sup_cnt < 2].apply(fn, axis=1)
print(df)
打印:
Subgroup cat1 cat2 cat3 sup_cnt
0 Group1 -1 -1 0 1
1 Group2 -1 22 -1 1
2 Group3 -1 14 -1 2
3 Group4 -1 -1 0 2