pandas 根据不同列范围的条件删除某列范围中的非唯一值

gudnpqoy  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(145)

这是df的一小部分。
在本例中,我需要Map3个y值:0.93388397.6583301.650013
我有这个df

x  y1  y2         y3         y4          d1  d2         d3         d4
23  5.3 NaN NaN   0.933883        NaN         NaN NaN   0.174866        NaN
25  5.3 NaN NaN        NaN  97.658330         NaN NaN        NaN   0.038670
26  5.3 NaN NaN   1.650013        NaN         NaN NaN   0.541264        NaN
29  5.3 NaN NaN  97.658330        NaN         NaN NaN  96.549581        NaN
30  5.3 NaN NaN        NaN   1.650013         NaN NaN        NaN  96.046987

每列中的这些值不超过一个,我已经删除了重复的值。

我需要的是:

不能在多个列中使用相同的值。
选择要删除的行的条件如下所示示例:
在列y3y4中存在97.658330。由于对于该值,d3(96.549581)大于d4(0.038670),因此删除了行29
y3y4中存在1.650013。由于d4(96.046987)大于d3(0.541264),因此删除了行30
输出量:

x  y1  y2         y3         y4          d1  d2         d3         d4
23  5.3 NaN NaN   0.933883        NaN         NaN NaN   0.174866        NaN
25  5.3 NaN NaN        NaN  97.658330         NaN NaN        NaN   0.038670
26  5.3 NaN NaN   1.650013        NaN         NaN NaN   0.541264        NaN

**P.S.**在完整的数据框中有更多的值需要Map。

lnvxswe2

lnvxswe21#

您可以用途:

y = df.filter(regex=r'y\d+')
d = df.filter(regex=r'd\d+')

# target = [0.933883, 97.658330, 1.650013]

# define the target values automatically
s = y.stack()
target = set(s[s.duplicated()])
# {1.650013, 97.65833}

drop = set()
for x in target:
    s = d.where(y.eq(x).to_numpy()).stack().droplevel(1)
    drop.update(s.index.difference([s.idxmin()]))

# drop is {29, 30}

out = df.drop(drop)

输出量:

x  y1  y2        y3        y4  d1  d2        d3       d4
23  5.3 NaN NaN  0.933883       NaN NaN NaN  0.174866      NaN
25  5.3 NaN NaN       NaN  97.65833 NaN NaN       NaN  0.03867
26  5.3 NaN NaN  1.650013       NaN NaN NaN  0.541264      NaN
toiithl6

toiithl62#

也许有一个更有效的解决方案,但这是可行的。 列y3y4中的值作为列表。然后查找 d3和d4的值,而y3和y4取共同的值?(v1,v2)。最后,根据指定的条件按索引号删除行。

vals=sorted(list(df[['y3','y4']].stack()))
dupes = list(set(vals[::2]) & set(vals[1::2])) #https://stackoverflow.com/a/64956890/15415267
#dupes= [1.650013, 97.65833]

for i in dupes:
    v1=df[df['y3']==i]['d3'].iloc[0]
    v2=df[df['y4']==i]['d4'].iloc[0]
    if v1 > v2:
        df=df.drop(df[df['y3']==i]['d3'].index)
    else:
        df=df.drop(df[df['y4']==i]['d4'].index)
print(df)
'''
      x  y1  y2        y3        y4  d1  d2        d3       d4
23  5.3 NaN NaN  0.933883       NaN NaN NaN  0.174866      NaN
25  5.3 NaN NaN       NaN  97.65833 NaN NaN       NaN  0.03867
26  5.3 NaN NaN  1.650013       NaN NaN NaN  0.541264      NaN
'''

相关问题