我有以下数据帧(实际上是几百MB长):
X Y Size
0 10 20 5
1 11 21 2
2 9 35 1
3 8 7 7
4 9 19 2
我要舍弃与数据帧中任何其他X,Y点之间的距离都小于X, Y
的{{1}}点。在那种情况下,我只想保留较大的行。
在此示例中,预期结果将是:
delta=3
答案 0 :(得分:1)
您可以使用以下脚本,也可以尝试对其进行改进。
#get all euclidean distances using sklearn;
#it will create an array of euc distances;
#then get index from df whose euclidean distance is less than 3
from sklearn.metrics.pairwise import euclidean_distances
Z = df[['X', 'Y']]
euc = euclidean_distances(Z, Z)
idx = [(i, j) for i in range(len(euc)-1) for j in range(i+1, len(euc)) if euc[i, j] < 3]
# collect all index of df that has euc dist < 3 and get the max value
# then collect all index in df NOT in euc and add the row with max size
# create a new called df_new by combining the rest in df and row with max size
from itertools import chain
df_idx = list(set(chain(*idx)))
df2 = df.iloc[df_idx]
idx_max = df2[df2['Size'] == df2['Size'].max()].index.tolist()
df_new = pd.concat([df.iloc[~df.index.isin(df_idx)], df2.iloc[idx_max]])
df_new
结果:
X Y Size
2 9 35 1
3 8 7 7
0 10 20 5
答案 1 :(得分:1)
正如问题所述,所需算法的行为尚不清楚如何处理距离链。
如果允许链接,则一种解决方案是使用基于密度的聚类算法(例如DBSCAN)对数据集进行聚类。
您只需要将邻域半径eps
设置为delta,并将min_sample
参数设置为1,以允许将孤立点作为聚类。然后,您可以在每个组中找到最大大小的点。
from sklearn.cluster import DBSCAN
X = df[['X', 'Y']]
db = DBSCAN(eps=3, min_samples=1).fit(X)
df['grp'] = db.labels_
df_new = df.loc[df.groupby('grp').idxmax()['Size']]
print(df_new)
>>>
X Y Size grp
0 10 20 5 0
2 9 35 1 1
3 8 7 7 2