Переместить строки с идентичными пространственными координатами в другой кластер в кадре данных pandas.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Переместить строки с идентичными пространственными координатами в другой кластер в кадре данных pandas.

Сообщение Anonymous »


У меня есть кадр данных pandas df. Столбцы широта и долгота представляют пространственные координаты людей.

импортировать панд как pd данные = { "широта": [49.5619579, 49.5619579, 49.56643220000001, 49.5719721, 49.5748542, 49.5757358, 49.5757358, 49.5757358, 49.5758638999 9999, 49.57182530000001, 49.5719721, 49.572026, 49.5727859, 49.5740071, 49.57500899999999, 49.5751017, 49.5751468, 49.57573 58, 49.5659508, 49.56611359999999, 49.5680586, 49.568089, 49.5687609 , 49.5699217, 49.572154, 49.5724688, 49.5733994, 49.5678048, 49.5702381, 49.5707702, 49.5710414, 49.5711228, 49.5713705, 49.5723685, 49.5725714, 49.5746149, 49.5631496, 49.5677449, 49.572268, 49.5724273, 49.5726773, 49.5739391, 49.5748542, 49.5 758151, 49.57586389999999, 49.5729483, 49.57321150000001, 49.5733375 , 49.5745175, 49.574758, 49.5748055, 49.5748103, 49.5751023, 49.57586389999999, 49.56643220000001, 49.5678048, 49.5679685 , 49.568089, 49.57182530000001, 49.5719721, 49.5724688, 49.5740071, 49.5757358, 49.5748542, 49.5758151, 49.5758151, 49.5758 151, 49.5758151, 49.5758151, 49.5758151, 49.5758151, 49.5758151, 49.5619579 , 49.5628938, 49.5630028, 49.5633175, 49.56397639999999, 49.5642962, 49.56643220000001, 49.5679685, 49.570056, 49.5619579 , 49.5724688, 49.5745175, 49.5748055, 49.5748055, 49.5748542, 49.5748542, 49.5751023, 49.5751023], "долгота": [10.9995758, 10.9995758, 10.9999593, 10.9910787, 11.0172739, 10.9920322, 10.9920322, 10.9920322, 11.0244747, 10.99103 98, 10.9910787, 10.9907713, 10.9885155, 10.9873742, 10.9861229, 10.9879312, 10.9872357, 10.9920322, 10.9873409, 10.9894231, 10.9882496, 10.9894035, 10.9887881 , 10.984756, 10.9911384, 10.9850981, 10.9852771, 10.9954673, 10.9993329, 10.9965937, 10.9949475, 10.9912959, 10.9939141, 10.9916605, 10.9983124, 10.992722, 11.0056254, 10.9954016, 11.017472, 11.0180908, 11.0181911, 11.0175466, 11.0172739, 11.02 49866, 11.0244747, 11.0200454, 11.019251, 11.0203055 , 11.0183162, 11.0252416, 11.0260046, 11.0228523, 11.0243391, 11.0244747, 10.9999593, 10.9954673, 10.9982288, 10.9894035, 10.9910398, 10.9910787, 10.9850981, 10.9873742, 10.9920322, 11.0172739, 11.0249866, 11.0249866, 11.0249866, 11.0249866, 11 .0249866, 11.0249866, 11.0249866, 11.0249866, 10.9995758 , 11.000319, 10.9990996, 10.9993819, 11.004145, 11.0039476, 10.9999593, 10.9982288, 10.9993409, 10.9995758, 10.9850981, 1 1.0183162, 11.0260046, 11.0260046, 11.0172739, 11.0172739, 11.0243391, 11.0243391] } df = pd.DataFrame(данные) Чтобы избежать кластеризации людей, живущих в одних и тех же пространственных координатах, я добавил дополнительные столбцы в df:

# добавить новую функцию df['feature_dub'] = df.groupby(['широта', 'долгота']).cumcount() df['IsDuulate'] = df.groupby(['latitude', 'longitude'])['feature_dub'].transform('count') > 1 df['IsDorm'] = df.groupby(['latitude', 'longitude'])['feature_dub'].transform('count') > 6 В приведенном выше коде я предполагаю, что если 6 люди имеют точные пространственные координаты, они живут в общежитии.

Следующий мой шаг:

df['feature_dorm'] = 0 # Фильтровать строки, где IsDorm имеет значение True маска = df['IsDorm'] # Используйте cumcount для подсчета ненулевых вхождений «IsDorm» в каждой группе «широты» и «долготы». df.loc[маска, 'feature_dorm'] = df[маска].groupby(['широта', 'долгота']).cumcount() + 1 Теперь я готов применить алгоритм кластеризации и надеюсь, что он выполнит свою работу

из k_means_constrained import KMeansConstrained координаты = np.column_stack((df["широта"], df["долгота"], df['feature_dub'], df['feature_dorm'])) # Определить количество кластеров и количество точек на кластер n_clusters = len(df) // 9 n_points_per_cluster = 9 # Выполняем кластеризацию с ограничением k-средних kmc = KMeansConstrained(n_clusters=n_clusters, size_min=n_points_per_cluster, size_max=n_points_per_cluster, random_state=42) kmc.fit(координаты) # Получить назначения кластера df["кластер"] = kmc.labels_ # Распечатываем кластеры для Cluster_num в диапазоне (n_clusters): кластерные_данные = df[df["кластер"] == номер_кластера][["широта", "долгота", "feature_dub", "feature_dorm",]] print(f"Кластер {cluster_num + 1}:") печать (cluster_data) После применения кластерного алгоритма под названием KMeansConstrained я получаю дополнительный столбец cluster. Каждый кластер содержит 9 рядов людей, живущих очень близко друг к другу:

импортировать панд как pd данные = { "широта": [49.5619579, 49.5619579, 49.56643220000001, 49.5719721, 49.5748542, 49.5757358, 49.5757358, 49.5757358, 49.5758638999 9999, 49.57182530000001, 49.5719721, 49.572026, 49.5727859, 49.5740071, 49.57500899999999, 49.5751017, 49.5751468, 49.57573 58, 49.5659508, 49.56611359999999, 49.5680586, 49.568089, 49.5687609 , 49.5699217, 49.572154, 49.5724688, 49.5733994, 49.5678048, 49.5702381, 49.5707702, 49.5710414, 49.5711228, 49.5713705, 49.5723685, 49.5725714, 49.5746149, 49.5631496, 49.5677449, 49.572268, 49.5724273, 49.5726773, 49.5739391, 49.5748542, 49.5 758151, 49.57586389999999, 49.5729483, 49.57321150000001, 49.5733375 , 49.5745175, 49.574758, 49.5748055, 49.5748103, 49.5751023, 49.57586389999999, 49.56643220000001, 49.5678048, 49.5679685 , 49.568089, 49.57182530000001, 49.5719721, 49.5724688, 49.5740071, 49.5757358, 49.5748542, 49.5758151, 49.5758151, 49.5758 151, 49.5758151, 49.5758151, 49.5758151, 49.5758151, 49.5758151, 49.5619579 , 49.5628938, 49.5630028, 49.5633175, 49.56397639999999, 49.5642962, 49.56643220000001, 49.5679685, 49.570056, 49.5619579 , 49.5724688, 49.5745175, 49.5748055, 49.5748055, 49.5748542, 49.5748542, 49.5751023, 49.5751023], "долгота": [10.9995758, 10.9995758, 10.9999593, 10.9910787, 11.0172739, 10.9920322, 10.9920322, 10.9920322, 11.0244747, 10.99103 98, 10.9910787, 10.9907713, 10.9885155, 10.9873742, 10.9861229, 10.9879312, 10.9872357, 10.9920322, 10.9873409, 10.9894231, 10.9882496, 10.9894035, 10.9887881 , 10.984756, 10.9911384, 10.9850981, 10.9852771, 10.9954673, 10.9993329, 10.9965937, 10.9949475, 10.9912959, 10.9939141, 10.9916605, 10.9983124, 10.992722, 11.0056254, 10.9954016, 11.017472, 11.0180908, 11.0181911, 11.0175466, 11.0172739, 11.02 49866, 11.0244747, 11.0200454, 11.019251, 11.0203055 , 11.0183162, 11.0252416, 11.0260046, 11.0228523, 11.0243391, 11.0244747, 10.9999593, 10.9954673, 10.9982288, 10.9894035, 10.9910398, 10.9910787, 10.9850981, 10.9873742, 10.9920322, 11.0172739, 11.0249866, 11.0249866, 11.0249866, 11.0249866, 11 .0249866, 11.0249866, 11.0249866, 11.0249866, 10.9995758 , 11.000319, 10.9990996, 10.9993819, 11.004145, 11.0039476, 10.9999593, 10.9982288, 10.9993409, 10.9995758, 10.9850981, 1 1.0183162, 11.0260046, 11.0260046, 11.0172739, 11.0172739, 11.0243391, 11.0243391], "кластер": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 , 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5 , 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8 , 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9] } df = pd.DataFrame(данные) Поскольку набор данных содержит много общежитий или больших зданий, может случиться так, что несколько человек будут иметь одинаковую широту и долготу и, следовательно, окажутся в одном кластере. Поэтому нам нужна некоторая постобработка: каждый раз, когда есть более двух человек с одинаковыми пространственными координатами, я хочу переместить одного (или несколько) из них в соседний кластер. Имейте в виду, я хочу переместить их не куда-то, а в кластер, который находится рядом (или относительно близко) к исходному кластеру.

Прежде всего я пытаюсь найти важные части:

duulate_rows = df[df.duulated(subset=["cluster", "latitude", "longitude"], Keep=False)] дубликаты_индексов = дубликаты_строк.индекс.толист() # Группировка по указанным столбцам и подсчет вхождений count_occurrences = df.iloc[dudicate_indices].groupby(['latitude', 'longitude', 'cluster']).size().reset_index(name='count') print("Количество строк с одинаковыми значениями в указанных столбцах:") печать (count_occurrences) Я понимаю:

Количество строк с одинаковыми значениями в указанных столбцах: количество кластеров широты и долготы 0 49.5619579000000030 10.9995758000000006 0 2 1 49.5748054999999965 11.0260046000000003 9 2 2 49.5748541999999972 11.0172738999999993 9 2 3 49.5751022999999975 11.0243391000000006 9 2 4 49.5757357999999968 10.9920322000000006 0 3 5 49.5758150999999998 11.0249866000000001 7 8 Индексы 0, 1, 2 и 3 подходят. Просто каждые два человека имеют одинаковые пространственные координаты. Я не хочу отвлекать людей оттуда, потому что значение 2 (и меньше) в count меня вполне устраивает! В общем, если возможно, я хочу, чтобы каждый человек остался в своем исходном кластере и вообще не перемещал человека, потому что это оптимальный кластер для этого человека. Однако оба индекса 4 и 5 представляют собой проблемы. Цель состоит в том, чтобы переместить некоторых людей с индексами 4 и 5 в соседние кластеры, чтобы минимизировать количество значений в count.

Что у меня есть на данный момент:

Основываясь на предыдущем вопросе о переполнении стека, у меня есть следующий код, который перемещает всех людей с одинаковыми пространственными координатами:
CLUSTER_SIZE = 9 df = df.drop(columns=["кластер"]) df_copy = df.copy(deep=True) дфс = [] пока правда: для номера_кластера в диапазоне (1 + df_copy.shape[0] // CLUSTER_SIZE): # Выбрать образец без дублирующихся координат пока правда: tmp = df_copy.sample(n=CLUSTER_SIZE, replace=False) если ( tmp.drop_duulates(subset=["широта", "долгота"]).shape[0] == CLUSTER_SIZE ): перерыв # Добавить новый номер кластера tmp["кластер"] = номер_кластера dfs.append(tmp) # Удалить образец из исходного фрейма данных df_copy = df_copy.drop(labels=tmp.index) если df_copy.shape[0]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»