Вычислить столбец из двух других, используя функцию с Pandas - PullRequest
0 голосов
/ 02 сентября 2018

Прежде всего, извинения, если этот вопрос повторяется, но я не могу решить свою проблему, используя объяснение в похожих вопросах ...

У меня есть функция, которая учитывает два параметра (широту и долготу), а затем вводит в Google API для извлечения города и страны этих координат. Эта функция выглядит следующим образом:

from urllib.request import urlopen
import json
def getplace(lat, lon):
    url = "http://maps.googleapis.com/maps/api/geocode/json?"
    url += "latlng=%s,%s&sensor=false" % (lat, lon)
    v = urlopen(url).read()
    j = json.loads(v)
    components = j['results'][0]['address_components']
    country = town = None
    for c in components:
        if "country" in c['types']:
            country = c['long_name']
        if "administrative_area_level_2" in c['types']:
            town = c['long_name']
    return town, country

У меня также есть база данных с элементами, где большинство из них (но не все) содержит поле с продольной и РАЗНОЕ поле с широтой. В некоторых строках также отсутствуют некоторые данные.

reference   name    lon        lat
0           name1   34.0055    1.0041
1           name1   NaN        NaN
2           name1   39.5632    3.6854
....

Как создать новое поле, прикрепленное к фрейму данных, которое содержит рассчитанное значение?

Я попробовал следующие утверждения безуспешно:

df['city'] = getplace(df['lon'], df['lat'])

И

df['city'] = df.apply(lambda x : coords(x['lon'], x['lat']) , axis=1)

Как лучше всего это сделать?

Заранее большое спасибо.

EDIT: Поэтому я изменил полный код на это:

from urllib.request import urlopen
import json
def getplace(lat, lon):
    if np.isnan(lat)==False:
        url = "http://maps.googleapis.com/maps/api/geocode/json?"
        url += "latlng=%s,%s&sensor=false" % (lat, lon)
        v = urlopen(url).read()
        j = json.loads(v)
        components = j['results'][0]['address_components']
        country = town = None
        for c in components:
            if "country" in c['types']:
                country = c['long_name']
            if "administrative_area_level_2" in c['types']:
                town = c['long_name']
        return town, country

import pandas as pd
import numpy as np
import matplotlib as plt
%matplotlib inline

df = pd.read_csv('items.csv')
df['city']=df.apply(lambda x : getplace(x['lat'], x['lon']) , axis=1)

По-прежнему не работает, отображается следующая ошибка:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-15-bffdb49e289b> in <module>()
----> 1 df['city']=df.apply(lambda x : getplace(x['lat'], x['lon']) , axis=1)

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, result_type, args, **kwds)
   6002                          args=args,
   6003                          kwds=kwds)
-> 6004         return op.get_result()
   6005 
   6006     def applymap(self, func):

~/anaconda3/lib/python3.6/site-packages/pandas/core/apply.py in get_result(self)
    140             return self.apply_raw()
    141 
--> 142         return self.apply_standard()
    143 
    144     def apply_empty_result(self):

~/anaconda3/lib/python3.6/site-packages/pandas/core/apply.py in apply_standard(self)
    246 
    247         # compute the result using the series generator
--> 248         self.apply_series_generator()
    249 
    250         # wrap results

~/anaconda3/lib/python3.6/site-packages/pandas/core/apply.py in apply_series_generator(self)
    275             try:
    276                 for i, v in enumerate(series_gen):
--> 277                     results[i] = self.f(v)
    278                     keys.append(v.name)
    279             except Exception as e:

<ipython-input-15-bffdb49e289b> in <lambda>(x)
----> 1 df['city']=df.apply(lambda x : getplace(x['lat'], x['lon']) , axis=1)

<ipython-input-10-ff447dcff3e8> in getplace(lat, lon)
      7         v = urlopen(url).read()
      8         j = json.loads(v)
----> 9         components = j['results'][0]['address_components']
     10         country = town = None
     11         for c in components:

IndexError: ('list index out of range', 'occurred at index 3')

Ниже приведена упрощенная версия файла, с которым я пытаюсь работать: https://drive.google.com/open?id=1Y3vtwage5kqxKWZIdQEwpy5qIP2KAGNT Большое спасибо

1 Ответ

0 голосов
/ 02 сентября 2018

Ваш второй пример работает должным образом (и будет идиоматическим пандой), если вы замените coords на getplace и убедитесь, что позаботились о строках, содержащих NaN s.

In [72]: df
Out[72]:
   reference   name      lon     lat
0          0  name1  34.0055  1.0041
1          1  name1      NaN     NaN
2          2  name1  39.5632  3.6854

In [73]: df['city'] = df.apply(lambda x: (None, None) if np.isnan(x.lon) or np.isnan(x.lat) else getplace(x.lon, x.lat), axis=1)

In [74]: df
Out[74]:
   reference   name      lon     lat             city
0          0  name1  34.0055  1.0041  (None, Algeria)
1          1  name1      NaN     NaN     (None, None)
2          2  name1  39.5632  3.6854    (None, Spain)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...