Python 在一个数据帧中获得小于1个单位的点

Python 在一个数据帧中获得小于1个单位的点,python,pandas,loops,Python,Pandas,Loops,我有一个熊猫数据帧(df),有超过18000个读数/点(Id为X[East]-Y读数[North])。我想迭代df,得到所有距离小于1个单位或彼此相距小于1个单位的点 我当前的代码通过使用2 for循环并遍历行、计算距离和打印if条件为真的情况来工作 for i, j in df.iterrows(): pnt, east, north = j[1], j[2], j[3] for l, k in df1.iterrows(): pnt1, east1, north1 = k[1],

我有一个熊猫数据帧(df),有超过18000个读数/点(Id为X[East]-Y读数[North])。我想迭代df,得到所有距离小于1个单位或彼此相距小于1个单位的点

我当前的代码通过使用2 for循环并遍历行、计算距离和打印if条件为真的情况来工作

for i, j in df.iterrows():
pnt, east, north = j[1], j[2], j[3]
for l, k in df1.iterrows():
    pnt1, east1, north1 = k[1], k[2], k[3]
    dist = math.hypot(east - east1, north - north1)
    if dist > 0 and dist < 1:
        print('Point {} is {}units away from point {}'.format(pnt, str(dist), pnt1))
df.iterrows()中i,j的

pnt,东,北=j[1],j[2],j[3]
对于df1.iterrows()中的l,k:
pnt1,east1,north1=k[1],k[2],k[3]
距离=数学形下(东-东1,北-北1)
如果距离>0且距离<1:
打印({}点距离{}点有{}个单位。格式(pnt、str(dist)、pnt1))
不确定是否需要,但我将数据帧复制到了df1,以查看代码是否运行得更快。虽然这是可行的,但它需要花费很长时间才能运行,并且想知道如何提高速度。

直接法 由于您没有提供获取真实数据的好方法,我创建了一个示例集用于演示:

 HoleID      East     North
      A  1.000000  2.000000
      B  1.351590  2.756961
      C  2.265317  3.174667
      D  2.599347  3.876338
      E  2.770851  4.407866
我想你要做的是将每个点与其他点进行比较,然后计算距离

为了实现这一点,您可以将数据帧本身连接到虚拟变量
x
上,这对于所有条目都是相同的,计算距离并过滤掉距离小于1的任何内容(无需运行计算该距离的平方根)

使用numpy和scipy
scipy
包包含
pdist
函数,用于计算点之间的成对距离。这可能会帮助您,甚至可以与您的大型数据集一起使用

要使用它,请尝试以下操作:

from scipy.spatial.distance import squareform, pdist

# calculate the pairwise distances
distances = pdist(df[["East", "North"]])
# now we select only those between 0 and 1, and create a symmetric matrix from the result
distances = squareform(np.where((distances < 1) & (distances > 0), distances, 0))
# finally we take the lower triangle of the matrix, create a dataframe
# and flatten it so we see every pair only once.
result = (
    pd.DataFrame(np.tril(distances), columns=df.HoleID, index=df.HoleID)
    .unstack()
    .loc[lambda x: x > 0]
)
print(result)

我很想知道您是否可以立即将此应用于整个数据帧。

谢谢。看起来我的数据集对于我的机器来说太大了。我收到以下错误:MemoryError:无法为具有形状(8338192100)和数据类型float64的数组分配20.2 GiB将尝试使数据集变小。避免出现内存问题的可能性是在您的建议和我的解决方案之间进行混合:将df拆分为多个块,对每个块运行合并(
df.merge(df[slice],on='x')。分配(…)
)并合并结果。你必须试着把这些切片制作得多大,这样才能把它保存在内存中。这就像炸弹一样有效。甚至不得不做一个混音。谢谢你介意投票表决我的答案吗?谢谢!
   HoleID_x HoleID_y  distance
1         A        B  0.834629
5         B        A  0.834629
13        C        D  0.777122
17        D        C  0.777122
19        D        E  0.558512
23        E        D  0.558512
from scipy.spatial.distance import squareform, pdist

# calculate the pairwise distances
distances = pdist(df[["East", "North"]])
# now we select only those between 0 and 1, and create a symmetric matrix from the result
distances = squareform(np.where((distances < 1) & (distances > 0), distances, 0))
# finally we take the lower triangle of the matrix, create a dataframe
# and flatten it so we see every pair only once.
result = (
    pd.DataFrame(np.tril(distances), columns=df.HoleID, index=df.HoleID)
    .unstack()
    .loc[lambda x: x > 0]
)
print(result)
HoleID  HoleID
A       B         0.834629
C       D         0.777122
D       E         0.558512
dtype: float64