#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных, который выглядит следующим образом
ID PC1 PC2 12 0.355 0.362 24 0.577 0.425 15 0.257 0.486 06 0.585 0.254 34 0.367 0.533
Я хочу использовать евклидово расстояние на PC1 и PC2, чтобы получить ближайшие точки данных.
Поэтому я хочу, чтобы, когда я ввожу ID = 15
python, я хотел, чтобы он дал мне список из 3 точек данных, которые находятся ближе всего. Желаемый результат будет выглядеть следующим образом.
ID PC1 PC2 Distance 34 0.367 0.533 ### 06 0.585 0.254 ### 12 0.355 0.462 ###
Приведенные выше цифры составлены, но я хочу, чтобы мои выходные данные выглядели именно так. ‘Расстояние » — это расстояние от входной точки данных (ID=15) до каждой соответствующей точки данных на выходе.
Я знаю, что это довольно просто, но я начинающий изучающий python. Я немного не уверен, как подойти к этому, так может ли кто-нибудь мне помочь? Спасибо.
Комментарии:
1. Вы уверены в своих результатах? Я нашел (34, 12, 24).
Ответ №1:
Если вам нужно запросить много точек, вы можете сначала построить KDTree
. Вот пример использования scipy
:
from scipy import spatial # WARNING: This assumes that all points in the DataFrame are distinct. # construct a KDTree given a set of points tree = spatial.cKDTree(df[["PC1", "PC2"]]) # get four = three one points closest to a given point (index 15 in this case) # the query point itself will be part of the output distances, indices = tree.query(df.loc[15].values, k=3 1) # get the df of near points df_near = df.iloc[indices[1:]].assign(Distance=distances[1:]) print(df_near) # PC1 PC2 Distance # ID # 34 0.367 0.533 0.119620 # 12 0.355 0.362 0.158051 # 24 0.577 0.425 0.325762
Комментарии:
1. Отлично, у нас одинаковый результат 🙂
2. Вы предполагаете, что столбец «ИДЕНТИФИКАТОР» является индексом фрейма данных (
df.loc[15]
). Я так не думаю, может быть, тебе и придетсяset_index
. Затем проверьте 4-й идентификатор -gt; ’06’, а не 6, поэтому тип dtype идентификатора столбца, вероятно, gt;str
и нетint
.3. И последний пункт (у меня была та же проблема…). Добавьте строку в начале вашего фрейма данных, например
03 0.257 0.486
. Вы отфильтруете «03» и сохраните «15».4. Я ценю, как это исправляет данный конкретный пример; однако этот подход потребует знания индекса запроса перед построением KDTree, что в некотором роде противоречит цели. Если требуется запросить только одну точку, нет необходимости создавать дерево KDTree.
5. Вы совершенно правы. Я согласен с этим.
Ответ №2:
Попробуй:
ID = '15' # Extract PC1, PC2 from current point (ID='15') point = df.loc[df['ID'] == ID, ['PC1', 'PC2']].squeeze() # Keep all other points others = df.loc[df['ID'] != ID, ['PC1', 'PC2']] # Compute the distance between the point and the other points # and keep the 3 points with the smallest distance dist = (others - point).pow(2).sum(1).pow(0.5).nsmallest(3) out = df.loc[dist.index].assign(Distance=dist)
Выход:
gt;gt;gt; out ID PC1 PC2 Distance 4 34 0.367 0.533 0.119620 0 12 0.355 0.362 0.158051 1 24 0.577 0.425 0.325762