Как выбрать несколько строк в кадре данных (гео) панд на основе массива или распространить метаданные результата алгоритма кластеризации? - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть фрейм данных геопанды, который содержит многоугольник, region_id и center_point lat и lon в радианах, который выглядит следующим образом:

enter image description here

Затем я хотел объединить каждую область по их центральной точке и сделал следующее:

#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]]) 

То, что я пытаюсь выяснить, как это сделать, - это получить region_ids, связанные с каждым кластером, чтобы объединить многоугольники, чтобы создать одну большую область без циклического прохождения через каждый кластер и для каждой пары широты и долготы и запроса кадра данных.

Есть ли способ распространения идентификаторов или опроса данных для каждого кластера?

Любая помощь здесь будет оценена.

Спасибо!

EDIT

Чего я хочу избежать, так это:

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 - и когда я пытаюсь это сделать, я получаю ошибку ключа:

Есть ли способ кластеризации на самих регионах, используя центральные точки в качестве свойств.

Спасибо

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Проверьте пример из skleanr (https://scikit -learn.org / stable / modules / generate / 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

Согласно описанию:

label_: array, shape = [n_samples] Метки кластера для каждой точки в набор данных, заданный для соответствия (). Шумным образцам присваивается метка -1.

В примере вы получаете две группы (метки 0 и 1). -1 - «шумная» выборка, здесь эта выборка явно больше, чем остальные.

Если вы делаете что-то похожее на это, у вас могут быть ваши регионы__ регионов и метка рядом друг с другом, и вы можете сравнить, есть ли отношение 1: 1 или нет.

0 голосов
/ 06 ноября 2018

Я думаю, что ваши группы в ваших ярлыках. Я думаю, что вы хотите, это (я использую 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
...