Применить функцию при условии Group ==

#python #pandas #dataframe #apply

#python #панды #фрейм данных #применить

Вопрос:

У меня есть Df следующим образом:

          position_latitude  position_longitude geohash
0                53.398940           10.069293      u1
1                53.408875           10.052669      u1
2                48.856350            9.171759      u0
3                48.856068            9.170798      u0
4                48.856350            9.171759      u0
  

Что я хочу знать, так это получение ближайшего узла к этим позициям с использованием разных шейп-файлов на основе Geohash.

Итак, что я хочу сделать, это загрузить навсегда group в Geohash (например, u1) график из файла, а затем использовать этот график в функции для получения ближайшего узла.

Я мог бы сделать это в цикле for, однако я думаю, что есть более эффективные способы сделать это.

Я думал о чем-то подобном:

 df['nearestNode'] = geoSub.apply(lambda x: getDistanceToEdge(x.position_latitude,x. position_longitude,x. geohash), axis=1)
  

Однако я не могу понять, как загружать график только один раз для каждой группы, поскольку для получения его из файла потребуется некоторое время.

что я придумал до сих пор:

 groupHashed = geoSub.groupby('geohash')
geoSub['distance'] = np.nan

for name, group in groupHashed:
    G = osmnx.graph.graph_from_xml('geohash/' name '.osm', simplify=True, retain_all=False)
    geoSub['distance'] = geoSub.apply(lambda x: getDistanceToEdge(x.position_latitude,x.position_longitude, G) if x.geohash == name, axis=1)
  

определенно, похоже, работает, однако я чувствую, что условие if резко замедляет его

обновление: только что обновлено:

 geoSub['distance'] = geoSub.apply(lambda x: getDistanceToEdge(x.position_latitude,x.position_longitude, G) if x.geohash == name, axis=1)
  

Для:

 geoSub['distance'] = geoSub[geoSub['geohash'] == name].apply(lambda x: getDistanceToEdge(x.position_latitude,x.position_longitude, G), axis=1)
  

теперь это намного быстрее. есть ли еще лучший метод?

Ответ №1:

Вы можете использовать transform

Я заглушаю G и getDistanceToEdge (как x y geohash[-1] ) поэтому показываю рабочий пример

 import pandas as pd
from io import StringIO 
data = StringIO("""
,position_latitude,position_longitude,geohash
0,53.398940,10.069293,u1
1,53.408875,10.052669,u1
2,48.856350,9.171759,u0
3,48.856068,9.170798,u0
4,48.856350,9.171759,u0
""" )
df = pd.read_csv(data, index_col=0).fillna('')

def getDistanceToEdge(x, y, G):
  return x y G

def fun(pos):  
  G = int(pos.values[0][-1][-1])
  return pos.apply(lambda x: getDistanceToEdge(x[0], x[1], G))

df['pos'] = list(zip(df['position_latitude'], df['position_longitude'], df['geohash']))
df['distance'] = df.groupby(['geohash'])['pos'].transform(fun)
df = df.drop(['pos'], axis=1)

print (df)
  

Вывод:

    position_latitude  position_longitude geohash   distance
0          53.398940           10.069293      u1  64.468233
1          53.408875           10.052669      u1  64.461544
2          48.856350            9.171759      u0  58.028109
3          48.856068            9.170798      u0  58.026866
4          48.856350            9.171759      u0  58.028109
  

Как вы можете видеть, вы можете получить имя группы, используя pos.values[0][-1] внутри функции fun . Это потому, что мы заботимся о том, чтобы создать pos столбец как кортеж (lat, log, geohash), и каждый geohash в группе после groupby одинаков. Таким образом, с помощью группы мы можем захватить geohash , взяв последнее значение кортежа ( pos ) любой строки. pos.values[0][-1] укажите последнее значение кортежа первой строки.

Комментарии:

1. большое спасибо, попробую вашу идею, так как моя последняя попытка (geoSub[‘distance’] = geoSub[geoSub[‘geohash’] == name].apply(lambda x: getDistanceToEdge(x.position_latity,x.position_longitude, G), axis = 1)) уже переопределяет всевычисленные значения равны nan — .-

2. У меня небольшая проблема с интерпретацией того, как вы хотите определить G в вашем примере, поскольку график зависит от имени группы. Итак, у меня есть один график в моей файловой системе для каждой группы, и мне нужно загрузить зависимый график в функцию fun. Не могли бы вы предоставить мне дополнительную информацию о том, как я мог бы решить ее на вашем примере? Смотрите: G = osmnx.graph.graph_from_xml(‘geohash/’ name ‘.osm’, simplify= True, retain_all=False)

3. Обновленный ответ с информацией