【问题标题】:Calculate column from two others using a function with Pandas使用 Pandas 的函数计算其他两个列
【发布时间】:2018-09-02 08:11:56
【问题描述】:

首先,如果这个问题重复出现,我深表歉意,但我无法使用类似问题中的解释来解决我的问题...

我有一个函数,它考虑两个参数(经度和纬度),然后输入 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

我还有一个包含项目的数据库,其中大多数(但不是全部)包含一个带有经度的字段和一个带有纬度的 DIFFERENT 字段。某些行中还缺少一些数据。

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

如何创建一个附加到包含计算值的 DataFrame 的新字段?

我尝试了以下语句,但没有成功:

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

还有:

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

最好的方法是什么?

非常感谢您。

编辑: 所以我把完整的代码改成这样:

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 非常感谢

【问题讨论】:

  • 您的第二种方法看起来像惯用的 pandas,但没有定义 coords(可能应该只是 getplace?)您将不得不处理 @987654331 中 NaN 输入的情况@虽然。
  • 计算值是什么意思?您是否尝试将您的功能用于 df['city'] ?

标签: python pandas


【解决方案1】:

如果您将 coords 替换为 getplace 并确保注意包含 NaNs 的行,您的第二个示例将按预期工作(并且将是惯用的 pandas)。

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)

【讨论】:

  • 您好,感谢您的重播您是对的,我没有看到函数的名称是错误的。现在它似乎工作了,但我总是收到一条错误消息: IndexError: ('list index out of range', 'occured at index 6') 每次执行代码时,'index'都会更改。是不是谷歌不允许我批量获取数据??
  • 什么是完整的回溯,发生时相关局部变量的值是多少?
  • 我已经编辑了原始帖子以提供更多信息。再次感谢!
  • @juancar:我在您输入的第二行中始终收到该错误;也就是说,resultsmaps.googleapis.com/maps/api/geocode/… 中是空的——stackoverflow.com/q/20910075/5085211 在这里可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 2022-10-14
  • 1970-01-01
相关资源
最近更新 更多