如何正确使用pandas中的.apply函数?

3

我正在处理一个包含“纬度”和“经度”列的百万行CSV数据集,我想基于此创建一个名为“州”的新列,该列是包含这些坐标的美国州。

import pandas as pd
import numpy as np
import os
from uszipcode import ZipcodeSearchEngine

def convert_to_state(coord):
    lat, lon = coord["latitude"], coord["longitude"]
    res = search.by_coordinate(lat, lon, radius=1, returns=1)
    state = res.State
    return state

def get_state(path):
    with open(path + "USA_downloads.csv", 'r+') as f:
        data = pd.read_csv(f)
        data["state"] = data.loc[:, ["latitude", "longitude"]].apply(convert_to_state, axis=1)

get_state(path)

我一直收到一个错误信息“ DtypeWarning:列(4,5)具有混合类型。指定导入时的 dtype 选项或将 low_memory = False。” 第4和5列对应纬度和经度。我不明白如何使用.apply来完成此任务,或者.apply是否是正确的方法。 我该怎么做?

1个回答

4
我相信这将是您程序更快的实现方式:
import pandas as pd
import numpy as np
import os
from uszipcode import ZipcodeSearchEngine

def convert_to_state(lat, lon):
    lat, lon = round(lat, 7), round(lon, 7)
    res = search.by_coordinate(lat, lon, radius=1, returns=1)
    state = res.State
    return state

def get_state(path):
    with open(path + "USA_downloads.csv", 'r+') as f:
        data = pd.read_csv(f)
        data["state"] = np.vectorize(convert_to_state)(data["latitude"].values, data["longitude"].values)

get_state(path)

它使用 numpy.vectorize 来加速处理(尽管仍然是循环),然后使用从 DataFrame 的 'latitude''longitude' 列获取的值调用该函数,转换为 numpy.ndarray.values 属性完成此操作)。
如果您想继续使用 .apply(),可以这样做:
state = data.apply(lambda x: convert_to_state(x['latitude'], x['longitude']), axis=1)
data["state"] = state

编辑

为了避免uszipcode引发TypeError,请使用以下方法:

def convert_to_state(lat, lon):
    try:
        res = search.by_coordinate(lat, lon, radius=1, returns=1)
        state = res.State
    except TypeError as TE:
        state = None
    return state

如果您想进一步调试uszipcode并找出导致错误的原因,我建议您提出另一个问题,并使用适当的标签,会有人帮助您。我没有使用过这个软件包,所以可能无法提供太多帮助。


1
@user1917407,谢谢!很高兴我能帮到你。 - Kartik
让我对此进行补充。经过一些调试,我仍然遇到了一些问题,尽管我不确定它是否源于我之前遇到的同样问题。我在这里的错误日志中看到纬度值要长得多,但是,在CSV文件本身中完全没有这种异常情况。有什么想法可以解决这个问题吗?http://pastebin.com/HZeZGNf2 - adamcircle
1
实际上,您遇到的是“dtype警告”,在大多数情况下可以忽略。对您的“get_state”函数进行以下更改:data = pd.read_csv(f, low_memory=False),然后编辑您的问题以包括此行的输出:print(df.dtypes)。进一步保护您的res = search.by_coordinate...在一个try .. except子句中,并打印引发异常的纬度和经度。我认为解决dtype冲突也将解决uszipcode引发的TypeError - Kartik
1
问题出在uszipcode上。你有两个选择,要么使用另一个包,要么按照我回答的后半部分进行更改。问题是,如果你进行更改,你的程序将正常工作,但是对于一些点,uszipcode会引发错误,你将无法获得信息。 - Kartik
1
此外,查看您的data.dtypes输出,纬度和经度列的类型为“对象”。这意味着某些纬度和经度不是严格的数字。您需要深入挖掘数据并找出哪些行没有数字。这在长期运行中也将非常有用。 - Kartik
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接