使用Pandas为每个过滤器确定列中最接近的值

2024-10-02 22:28:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含类别和值的数据框。我需要找到每个类别中最接近某个值的值。我想我已经很接近了,但是在将argsort的结果应用于原始数据帧时,我不能真正得到正确的输出。在

例如,如果输入是在下面的代码中定义的,那么输出应该只有(a, 1, True)(b, 2, True)(c, 2, True),而所有其他isClosestValues应该为False。在

如果多个值最接近,则它应该是列出的第一个标记的值。在

这是我的代码,但我不能让它重新应用到数据帧正确。我想要一些指点。在

df = pd.DataFrame()
df['category'] = ['a', 'b', 'b', 'b', 'c', 'a', 'b', 'c', 'c', 'a']
df['values'] = [1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
df['isClosest'] = False

uniqueCategories = df['category'].unique()
for c in uniqueCategories:
    filteredCategories = df[df['category']==c]    
    sortargs = (filteredCategories['value']-2.0).abs().argsort()
    #how to use sortargs so that we set column in df isClosest=True if its the closest value in each category to 2.0?

Tags: to数据代码infalsetruedfvalue
2条回答

您可以创建一列绝对差异:

df['dif'] = (df['values'] - 2).abs()

df
Out: 
  category  values  dif
0        a       1    1
1        b       2    0
2        b       3    1
3        b       4    2
4        c       5    3
5        a       4    2
6        b       3    1
7        c       2    0
8        c       1    1
9        a       0    2

然后使用groupby.transform检查每组的最小值是否等于您计算的差值:

^{pr2}$

df.groupby('category')['dif'].idxmin()还将为每个类别提供最接近值的索引。你也可以用它来绘制地图。在

供选择:

df.loc[df.groupby('category')['dif'].idxmin()]
Out: 
  category  values  dif
0        a       1    1
1        b       2    0
7        c       2    0

对于分配:

df['is_closest'] = False
df.loc[df.groupby('category')['dif'].idxmin(), 'is_closest'] = True
df
Out: 
  category  values  dif is_closest
0        a       1    1       True
1        b       2    0       True
2        b       3    1      False
3        b       4    2      False
4        c       5    3      False
5        a       4    2      False
6        b       3    1      False
7        c       2    0       True
8        c       1    1      False
9        a       0    2      False

这些方法之间的区别在于,如果您将相等与差异进行比较,则对于所有行,在ties的情况下,都将为True。但是,使用idxmin时,它将在第一次出现时返回True(每个组只返回一个)。在

使用^{}的解决方案-获取每组最小值的索引,然后按^{}将布尔掩码分配给列isClosest

idx = (df['values'] - 2).abs().groupby([df['category']]).idxmin()
print (idx)
category
a    0
b    1
c    7
Name: values, dtype: int64

df['isClosest'] = df.index.isin(idx)
print (df)
  category  values isClosest
0        a       1      True
1        b       2      True
2        b       3     False
3        b       4     False
4        c       5     False
5        a       4     False
6        b       3     False
7        c       2      True
8        c       1     False
9        a       0     False

相关问题 更多 >