<p>在k维空间中寻找最近邻是k-d树数据结构(<a href="https://en.wikipedia.org/wiki/K-d_tree" rel="nofollow noreferrer">Wikipedia</a>)的一个经典例子。sciketlearn有一个灵活的实现(<a href="https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html" rel="nofollow noreferrer">docs</a>),我在下面使用它,因为您的问题中使用的条件逻辑似乎定义了Chebyshev距离度量(<a href="https://en.wikipedia.org/wiki/Chebyshev_distance" rel="nofollow noreferrer">Wikipedia</a>),sciketlearn本机支持这个度量。SciPy的<code>cKDTree</code>(<a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.cKDTree.html" rel="nofollow noreferrer">docs</a>,<a href="https://github.com/scipy/scipy/tree/master/scipy/spatial/ckdtree/src" rel="nofollow noreferrer">C++ source code</a>)只支持欧几里德(L2)距离度量,但是针对它进行了优化,因此可能更快。你知道吗</p>
<pre><code># Setup
df = pd.DataFrame({'id':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],
'x':[-2,-2,-2,-1,-1,-1,-1,0,0,0,0,0,1,1,1,1,2,2,2],
'y':[2,1,0,2,1,0,-1,2,1,0,-1,-2,1,0,-1,-2,0,-1,-2],
'z':[0,1,2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,-2,-1,0],
'val':[0,0,0,1,0,0,6,3,7,11,0,0,14,18,10,4,20,15,2]})
df.set_index('id', inplace=True)
from sklearn.neighbors import KDTree
# Build k-d tree with the Chebyshev metric, AKA L-infinity
tree = KDTree(df[['x', 'y', 'z']].values, metric='chebyshev')
for radius in [0, 1, 2]:
# Populate new column with placeholder integer
df[f'n{radius}'] = -1
for i, row in df.iterrows():
coords = row[['x', 'y', 'z']].values.reshape(1, -1)
idx = tree.query_radius(coords, r=radius)[0]
df.loc[i, f'n{radius}'] = df.iloc[idx]['val'].sum()
df
x y z val n0 n1 n2
id
1 -2 2 0 0 0 1 22
2 -2 1 1 0 0 0 25
3 -2 0 2 0 0 6 17
4 -1 2 -1 1 1 11 54
5 -1 1 0 0 0 19 70
6 -1 0 1 0 0 17 57
7 -1 -1 2 6 6 6 31
8 0 2 -2 3 3 25 74
9 0 1 -1 7 7 54 99
10 0 0 0 11 11 46 111
11 0 -1 1 0 0 31 73
12 0 -2 2 0 0 10 33
13 1 1 -2 14 14 62 99
14 1 0 -1 18 18 95 105
15 1 -1 0 10 10 60 107
16 1 -2 1 4 4 16 66
17 2 0 -2 20 20 67 100
18 2 -1 -1 15 15 65 101
19 2 -2 0 2 2 31 80
</code></pre>