Я рассчитываю расстояние до работы (от дома до офиса) для всех сотрудников. Это работает для одного офиса с этим фрагментом кода:
#Calculate distances from home to all other offices
def distances_to_offices(row):
row['distance_to_office'] = round(distance.distance(row['Home_geocode'], row['Office_geocode']).km,0)
return row
df_joined.apply(distances_to_offices, axis=1)
У меня есть много офисов, и я хотел бы пройтись по ним, создав новый столбец для расстояний для каждого офиса. Функция вызывается без аргумента, но в качестве параметра в определении функции задана строка. Когда я пытаюсь передать название города, мне нужно вызвать функцию с тем же количеством аргументов, что и в определении функции, но это не работает, поскольку «строка» не понимается как аргумент:
NameError: name 'row' is not defined
Я не понимаю, почему «строка» работает как аргумент в определении функции, но не тогда, когда я пытаюсь вызвать ее с этим аргументом. Кто может помочь пролить свет? Я думаю о чем-то подобном, но борюсь с выбором правильных аргументов:
# throws Name Error:
def distances_to_offices(row, city):
col_name = city + "_distance"
row[col_name] = round(distance.distance(row['Home_geocode'], row['Office_geocode']).km,0)
return row
offices = ['NY', 'Rio', 'Tokyo']
for city in offices:
df_joined.apply(distances_to_offices(row, city), axis=1)
Не могу сказать точно, потому что я не знаю, что такое df_joined, но похоже, что это какой-то объект, представляющий таблицу данных, для которой вы можете вызвать apply()
передачу функции, а apply()
будет перебирать таблицу, вызывая функцию вы указали при передаче индекс строки или имя для каждой строки таблицы данных.
Первый способ, которым вы это сделали, работает, потому что вы передаете ИМЯ функции distances_to_offices
в apply(), а apply() вызывает ее с row
, который определяется в каком-то цикле for, который он устанавливает.
Второй способ, которым вы это сделали, терпит неудачу, потому что вы больше не передаете ИМЯ distances_to_offices
, а вместо этого ВЫЗЫВАЕТЕ его с аргументами row
и city
, а затем передаете результат вызова этой функции в качестве аргумента apply()
. Это не может работать, потому что вы не определили, что такое row
, но Python должен знать, что такое row
, чтобы выполнить вызов функции distances_to_offices(row, city)
, который происходит ДО того, как приложение увидит его и получит возможность определить row
.
Я не уверен, как работает df_joined.apply(), поэтому без дополнительной информации я не могу сказать, как правильно это сделать. Одной из стратегий было бы создание нового объекта таблицы данных на каждой итерации цикла путем фильтрации df_joined, чтобы сохранить только строки, в которых есть город, соответствующий city
.
Я понял, что вызов функции отличается от ее применения. Поэтому я переместил цикл for в функцию, чтобы получить желаемый результат: row[col_name] = round(distance.distance(row['Home_geocode'], row[city]).km,0) return row df_joined.apply(distances_to_offices, axis=1)` (не уверен, почему `` не превратить его в уценку кода)