基本上,我在两个不同的列中有纬度和经度(在网格上)。我得到了一个新坐标集的两个元素列表(可能是numpy数组),我想在添加它之前检查它是否重复。
例如,我的数据:
df = pd.DataFrame([[4,8, 'wolf', 'Predator', 10],
[5,6,'cow', 'Prey', 10],
[8, 2, 'rabbit', 'Prey', 10],
[5, 3, 'rabbit', 'Prey', 10],
[3, 2, 'cow', 'Prey', 10],
[7, 5, 'rabbit', 'Prey', 10]],
columns = ['lat', 'long', 'name', 'kingdom', 'energy'])
newcoords1 = [4,4]
newcoords2 = [7,5]
是否可以编写一个if
语句来告诉我是否已存在具有该纬度和经度的行。在伪代码中:
if newcoords1 in df['lat', 'long']:
print('yes! ' + str(newcoords1))
(在示例中,newcoords1
应为false
,newcoords2
应为true
。
旁注:(newcoords1[0] in df['lat']) & (newcoords1[1] in df['long'])
无法正常工作,因为它会独立检查,但我需要知道该组合是否出现在一行中。
提前谢谢!
答案 0 :(得分:5)
你可以这样做:
In [140]: df.query('@newcoords2[0] == lat and @newcoords2[1] == long')
Out[140]:
lat long name kingdom energy
5 7 5 rabbit Prey 10
In [146]: df.query('@newcoords2[0] == lat and @newcoords2[1] == long').empty
Out[146]: False
以下行将返回多个找到的行:
In [147]: df.query('@newcoords2[0] == lat and @newcoords2[1] == long').shape[0]
Out[147]: 1
或使用NumPy方法:
In [103]: df[(df[['lat','long']].values == newcoords2).all(axis=1)]
Out[103]:
lat long name kingdom energy
5 7 5 rabbit Prey 10
这将显示是否至少找到了一行:
In [113]: (df[['lat','long']].values == newcoords2).all(axis=1).any()
Out[113]: True
In [114]: (df[['lat','long']].values == newcoords1).all(axis=1).any()
Out[114]: False
说明:
In [104]: df[['lat','long']].values == newcoords2
Out[104]:
array([[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[ True, True]], dtype=bool)
In [105]: (df[['lat','long']].values == newcoords2).all(axis=1)
Out[105]: array([False, False, False, False, False, True], dtype=bool)
答案 1 :(得分:2)
x, y = newcoords1
>>> df[(df.lat == x) & (df.long == y)].empty
True # Coordinates are not in the dataframe, so you can add it.
x, y = newcoords2
>>> df[(df.lat == x) & (df.long == y)].empty
False # Coordinates already exist.
答案 2 :(得分:2)
对于像我这样的人来说,他们是通过搜索如何检查大数据框内的一对列中是否存在几对值来找到答案的。
让一个列表newscoord = [newscoord1, newscoord2, ...]
并提取与该列表元素匹配的df
行。然后对于上面的示例:
v = pd.Series( [ str(i) + str(j) for i,j in df[['lat', 'long']].values ] )
w = [ str(i) + str(j) for i,j in newscoord ]
df[ v.isin(w) ]
与@MaxU提供相同的输出,但允许一次提取多行。
在我的计算机上,对于具有10,000行的df
,运行时间为0.04秒。
当然,如果您的元素已经是字符串,则使用join
而不是串联更为简单。
此外,如果成对的元素的顺序无关紧要,则必须先排序:
v = pd.Series( [ str(i) + str(j) for i,j in np.sort( df[['lat','long']] ) ] )
w = [ str(i) + str(j) for i,j in np.sort( newscoord ) ]
要注意的是,如果v
未转换为序列并且使用np.isin(v,w)
,或者i w
被转换为序列,则在{{ 1}}达到了数千个元素。
希望有帮助。