Melhor maneira para percorrer trama de dados para chamar a API do Google distância

Groszours:

Eu gostaria de saber qual é a melhor solução para obter distâncias a partir da API do Google Maps distância para o meu trama de dados composto por coordenadas (origem e destino), que é de cerca de 75k linhas.

    #Origin                     #Destination

1   (40.7127837, -74.0059413)   (34.0522342, -118.2436849)
2   (41.8781136, -87.6297982)   (29.7604267, -95.3698028)
3   (39.9525839, -75.1652215)   (40.7127837, -74.0059413)
4   (41.8781136, -87.6297982)   (34.0522342, -118.2436849)
5   (29.7604267, -95.3698028)   (39.9525839, -75.1652215)

Até agora o meu código itera através da trama de dados e chama a API copiar o valor da distância para a nova coluna "distância".

df['distance'] = ""

for index, row in df.iterrows():
    result = gmaps.distance_matrix(row['origin'], row['destination'], mode='driving')
    status = result['rows'][0]['elements'][0]['status']
    if status == "OK":                               # Handle "no result" exception
        KM = int(result['rows'][0]['elements'][0]['distance']['value'] / 1000)
        df['distance'].iloc[index] = KM
    else:
        df['distance'].iloc[index] = 0

df.to_csv('distance.csv')

Eu obter o resultado desejado, mas pelo que tenho a iteração leitura através trama de dados é bastante ineficiente e deve ser evitado. Demorou 20 secondes para 240 linhas, de modo que seria necessário 1h30 para fazer tudo trama de dados. Note-se que, uma vez feito, não há necessidade de mais re-run, apenas novos poucas novas linhas por mês (~ 500).

O que seria de nós a melhor solução aqui?

Edit: se alguém tem experiência com a API do Google distância e suas limitações qualquer dicas / melhores práticas é bem-vinda.

rpanai:

Tentei entender sobre quaisquer limitações sobre chamadas simultâneas aqui , mas eu não consegui encontrar nada. algumas sugestões

loops de Evitar

Sobre o seu código Prefiro pular para loops e utilização aplicam-se primeiro

def get_gmaps_distance(row):
    result = gmaps.distance_matrix(row['origin'], row['destination'], mode='driving')
    status = result['rows'][0]['elements'][0]['status']
    if status == "OK":
        KM = int(result['rows'][0]['elements'][0]['distance']['value'] / 1000)
    else:
        KM = 0
    return KM

df["distance"] = df.apply(get_gmaps_distance, axis=1)

Dividir a sua trama de dados e uso de multiprocessamento

import multiprocessing as mp

def parallelize(fun, vec, cores=mp.cpu_count()):
    with mp.Pool(cores) as p:
        res = p.map(fun, vec)
    return res

# split your dataframe in many chunks as the number of cores

df = np.array_split(df, mp.cpu_count())

# this use your functions for every chunck 
def parallel_distance(x):
    x["distance"] = x.apply(get_gmaps_distance, axis=1)
    return x

df = parallelize(parallel_distance, df)

df = pd.concat(df, ignore_index=True, sort=False)

Não calcule duas vezes a mesma distância (save $$$)

No caso de ter duplicatas linha que você deve deixar cair alguns deles

grp = df.drop_duplicates(["origin", "destination"]).reset_index(drop=True)

Aqui eu não substituiu dfcomo ele possivelmente conter mais informações que você precisa e você pode mesclar os resultados a ele.

grp["distance"] = grp.apply(get_gmaps_distance, axis=1)

df = pd.merge(df, grp, how="left")

reduzir decimais

Você deve perguntar-lhe esta pergunta: eu realmente preciso para ser exato para o 7º decimal? Como um grau de latitude é de aproximadamente 111 km a 7ª casa decimal lhe dá uma precisão de até ~ um centímetro. Você começa a idéia deste quando menos-é-mais onde a redução decimais Eles melhoraram o modelo.

Conclusão

Se você pode, eventualmente, usar todos os métodos sugeridos você poderia obter algumas melhorias interessantes. Eu gostaria que você comentasse-los aqui como eu não tenho uma chave de API pessoal para tentar sozinho.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=373060&siteId=1
Recomendado
Clasificación