首页 > 解决方案 > 检查数据框值 +/- 1 是否存在于给定列中的其他任何位置

问题描述

假设我有一个如下所示的数据框 df:

   irrelevant   location
0           1          0
1           2          0
2           3          1
3           4          3     

如何创建一个新的真/假列“邻居”来指示“位置”+/- 1(正负 1)中的值是否存在于“位置”列中的其他任何位置。这样:

   irrelevant   location   neighbor
0           1          0       True
1           2          0       True
2           3          1       True
3           4          3       False

最后一行是假的,因为 df.location 列中的任何地方都没有出现 2 和 4。

我试过这些:

>>> df['neighbor']=np.where((df.location+1 in df.location.unique())|(df.location-1 in df.x.unique()), True, False)

ValueError: Lengths must match to compare

>>> df['tmp']=np.where((df.x+1 in df.x.tolist())|(df.x-1 in df.x.tolist()), 'true', 'false')

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

或者,提前感谢您的帮助,将我引导到这个问题的早期实例(我似乎没有合适的词汇来找到它们)。

标签: pythonpandasnumpydataframe

解决方案


要在列中的任何位置查找邻居,请创建所有邻居值的列表,然后检查isin.

import numpy as np

vals = np.unique([df.location+1, df.location-1])
#array([-1,  0,  1,  2,  4], dtype=int64)

df['neighbor'] = df['location'].isin(vals)
#   irrelevant  location  neighbor
#0           1         0      True
#1           2         0      True
#2           3         1      True
#3           4         3     False

正因为,这也可以通过pd.merge_asof设置容差来找到邻居。我们设置一个 True 值,如果存在邻居,则在合并中引入该值。否则,它会留下 NaN,我们在合并后用 False 填充。

(pd.merge_asof(df, 
               df[['location']].assign(neighbor=True),
               on='location',
               allow_exact_matches=False,  # Don't match with same value
               direction='nearest',        # Either direction
               tolerance=1)                # Within 1, inclusive
   .fillna(False)) 

推荐阅读