如何 select 基于数组的 (geo)pandas 数据帧中的多行或传播聚类算法结果的元数据?
How to select multiple rows from a (geo)pandas dataframe based on an array or propagate metadata of a clustering algorithm result?
我有一个包含多边形的 geopandas 数据框,region_id 和 center_point 纬度和经度,看起来像这样:
然后我想根据中心点对每个区域进行聚类并执行以下操作:
#Set Up
kms_per_radian = 6371.0088
eps = 0.1/kms_per_radian
coords = blocks_meta.as_matrix(columns=['lat', 'lon'])
#Cluster
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=epsilon, algorithm='ball_tree', metric='haversine', min_samples=1).fit(coords)
labels = db.labels_
clusters = pd.Series([coords[labels == n] for n in range(len(set(labels)))])
这会产生一组中心点簇,如下所示。
array([[ 0.0703843 , 0.170845 ],
[ 0.07037922, 0.17084981],
[ 0.07036705, 0.17085678],
[ 0.0703715 , 0.17083775]])
我正在努力弄清楚如何做的是让 regions_ids 与每个集群相关联以合并多边形以创建一个更大的区域,而无需循环遍历每个集群以及每个纬度、经度对和查询数据框。
是否有传播 ID 或查询每个集群的数据帧的方法?
如有任何帮助,我们将不胜感激。
谢谢!
编辑
我想避免的是这样做:
clusters_of_regions = []
for cluster in clusters:
cluster_of_regions_ids = []
for entry in cluster:
print(cluster[0][0])
region_id = blocks_meta.loc[blocks_meta['lat'] == cluster[0][0]]['region_id'][1]
cluster_of_regions_ids.append(region_id)
clusters_of_regions.append(cluster_of_regions_ids)
两者都是为了避免嵌套的 for 循环 - 每当我尝试时,我都会不断收到关键错误:
有没有一种方法可以使用中心点作为属性对区域本身进行聚类。
谢谢
我认为您的群组在您的标签中。
我想你想要的是这个(我用的是labels = [1,2,3,4]
):
df1 = pd.DataFrame(ar)
df1.loc[:,'labels'] = pd.Series(labels)
df1
这将创建一个像这样的 df :
0 1 labels
0 0.070384 0.170845 1
1 0.070379 0.170850 2
2 0.070367 0.170857 3
3 0.070372 0.170838 4
检查来自 skleanr (https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html) 的示例。我在这里修改它以拥有一个数据框并且类似于您的示例。
from sklearn.cluster import DBSCAN
import pandas as pd
import numpy as np
X = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])
df = pd.DataFrame(X, index=list(range(len(X))), columns = ['col1', 'col2'])
clustering = DBSCAN(eps = 3, min_samples = 2).fit(df)
labels = clustering.labels_
df = df.merge(pd.Series(labels).to_frame().rename(columns={0:'clusters'}), left_index = True, right_index = True, how = 'outer')
df
给你:
col1 col2 clusters
0 1 2 0
1 2 2 0
2 2 3 0
3 8 7 1
4 8 8 1
5 25 80 -1
根据描述:
labels_ : array, shape = [n_samples] Cluster labels for each point in
the dataset given to fit(). Noisy samples are given the label -1.
在示例中,您得到两个组(标签 0 和 1)。 -1 是一个 'noisy' 样本,这里的样本明显大于其他样本。
如果你做类似的事情,你可以将你的 regions_id 和标签放在一起,比较是否存在 1:1 关系。
我有一个包含多边形的 geopandas 数据框,region_id 和 center_point 纬度和经度,看起来像这样:
然后我想根据中心点对每个区域进行聚类并执行以下操作:
#Set Up
kms_per_radian = 6371.0088
eps = 0.1/kms_per_radian
coords = blocks_meta.as_matrix(columns=['lat', 'lon'])
#Cluster
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=epsilon, algorithm='ball_tree', metric='haversine', min_samples=1).fit(coords)
labels = db.labels_
clusters = pd.Series([coords[labels == n] for n in range(len(set(labels)))])
这会产生一组中心点簇,如下所示。
array([[ 0.0703843 , 0.170845 ],
[ 0.07037922, 0.17084981],
[ 0.07036705, 0.17085678],
[ 0.0703715 , 0.17083775]])
我正在努力弄清楚如何做的是让 regions_ids 与每个集群相关联以合并多边形以创建一个更大的区域,而无需循环遍历每个集群以及每个纬度、经度对和查询数据框。
是否有传播 ID 或查询每个集群的数据帧的方法?
如有任何帮助,我们将不胜感激。
谢谢!
编辑
我想避免的是这样做:
clusters_of_regions = []
for cluster in clusters:
cluster_of_regions_ids = []
for entry in cluster:
print(cluster[0][0])
region_id = blocks_meta.loc[blocks_meta['lat'] == cluster[0][0]]['region_id'][1]
cluster_of_regions_ids.append(region_id)
clusters_of_regions.append(cluster_of_regions_ids)
两者都是为了避免嵌套的 for 循环 - 每当我尝试时,我都会不断收到关键错误:
有没有一种方法可以使用中心点作为属性对区域本身进行聚类。
谢谢
我认为您的群组在您的标签中。
我想你想要的是这个(我用的是labels = [1,2,3,4]
):
df1 = pd.DataFrame(ar)
df1.loc[:,'labels'] = pd.Series(labels)
df1
这将创建一个像这样的 df :
0 1 labels
0 0.070384 0.170845 1
1 0.070379 0.170850 2
2 0.070367 0.170857 3
3 0.070372 0.170838 4
检查来自 skleanr (https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html) 的示例。我在这里修改它以拥有一个数据框并且类似于您的示例。
from sklearn.cluster import DBSCAN
import pandas as pd
import numpy as np
X = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])
df = pd.DataFrame(X, index=list(range(len(X))), columns = ['col1', 'col2'])
clustering = DBSCAN(eps = 3, min_samples = 2).fit(df)
labels = clustering.labels_
df = df.merge(pd.Series(labels).to_frame().rename(columns={0:'clusters'}), left_index = True, right_index = True, how = 'outer')
df
给你:
col1 col2 clusters
0 1 2 0
1 2 2 0
2 2 3 0
3 8 7 1
4 8 8 1
5 25 80 -1
根据描述:
labels_ : array, shape = [n_samples] Cluster labels for each point in the dataset given to fit(). Noisy samples are given the label -1.
在示例中,您得到两个组(标签 0 和 1)。 -1 是一个 'noisy' 样本,这里的样本明显大于其他样本。
如果你做类似的事情,你可以将你的 regions_id 和标签放在一起,比较是否存在 1:1 关系。