为啥在定义全局名称时出现错误?

Posted

技术标签:

【中文标题】为啥在定义全局名称时出现错误?【英文标题】:Why do I have an error when the global name has been defined?为什么在定义全局名称时出现错误? 【发布时间】:2019-03-12 11:59:01 【问题描述】:

我正在尝试使用 python 按照答案here 中的步骤计算时间排序坐标之间的距离和速度。在代码的最后,我遇到了一个错误,它说全局名称尚未定义,但很明显它已经定义了。

这是我的数据样本

    ID  timestamp           latitude        longitude
0   72  20/01/2015 09:47    -6.646405565    71.35696828
1   72  20/01/2015 15:47    -6.642237759    71.36032005
2   72  20/01/2015 21:47    -6.639229675    71.36914769
3   73  21/01/2015 03:47    -6.648699053    71.37865551
4   73  21/01/2015 09:47    -6.65574147     71.37957366
5   74  21/01/2015 15:47    -6.660118996    71.37990588
6   74  21/01/2015 21:47    -6.666138734    71.38266541

到目前为止,我已经能够运行以下代码

import pandas as pd
df = pd.read_csv(filename)  

df['timestamp'] = pd.to_datetime(df['timestamp'], format='%d/%m/%Y %H:%M')

from math import sin, cos, sqrt, atan2, radians

def getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2):
    R = 6371 # Radius of the earth in km
    dLat = radians(lat2-lat1)
    dLon = radians(lon2-lon1)
    rLat1 = radians(lat1)
    rLat2 = radians(lat2)
    a = sin(dLat/2) * sin(dLat/2) + cos(rLat1) * cos(rLat2) * sin(dLon/2) * sin(dLon/2) 
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    d = R * c # Distance in km
    return d

def calc_velocity(dist_km, time_start, time_end):
    """Return 0 if time_start == time_end, avoid dividing by 0"""
    return dist_km / (time_end - time_start).seconds if time_end > time_start else 0

# First sort by ID and timestamp:
df = df.sort_values(by=['ID', 'timestamp'])

# Group the sorted dataframe by ID, and grab the initial value for lat, lon, and time.
df['lat0'] = df.groupby('ID')['latitude'].transform(lambda x: x.iat[0])
df['lon0'] = df.groupby('ID')['longitude'].transform(lambda x: x.iat[0])
df['t0'] = df.groupby('ID')['timestamp'].transform(lambda x: x.iat[0])

# create a new column for distance
df['dist_km'] = df.apply(
    lambda row: getDistanceFromLatLonInKm(
        lat1=row['latitude'],
        lon1=row['longitude'],
        lat2=row['lat0'],
        lon2=row['lon0']
    ),
    axis=1
)

此时,我收到一个错误,暗示'getDistanceFromLatLonInKm' 尚未定义,尽管它已经定义。下面是回溯和错误

Traceback (most recent call last):
  File "<pyshell#36>", line 9, in <module>
    axis=1
  File "C:\Python27\ArcGIS10.6\lib\site-packages\pandas\core\frame.py", line 4061, in apply
    return self._apply_standard(f, axis, reduce=reduce)
  File "C:\Python27\ArcGIS10.6\lib\site-packages\pandas\core\frame.py", line 4157, in _apply_standard
    results[i] = func(v)
  File "<pyshell#36>", line 3, in <lambda>
    lambda row: getDistanceFromLatLonInKm(
NameError: ("global name 'getDistanceFromLatLonInKm' is not defined", u'occurred at index 0')

这段代码哪里出错了?

【问题讨论】:

请发布您的错误的完整追溯 抱歉,我已经更新了我的问题以包括在内。 您应该将代码保存在文件中并运行它。 我在堆栈跟踪中看到了 pyshell。你能把所有东西都放在一个 python 脚本中并作为 'python ' 运行吗?我能够使用您链接的问题中的 csv 文件运行您的代码而没有任何错误。 @Manoj Mohan 正如我在下面的评论中承认的那样,我以前没有使用过 python,所以我不确定你的意思。我知道这不是手动服务,所以我会说声谢谢并尝试解决。很高兴知道代码有效,只有我需要学习如何使用它。 【参考方案1】:

如果您需要有关执行 Python 代码的不同方式的背景知识,请查看此链接。 https://realpython.com/run-python-scripts/

将以下代码复制粘贴到文件中,并将文件另存为 lat_long.py。根据您的系统仅更改 csv 文件名“lat_long.csv”。在 shell 或命令提示符下,执行命令:

python lat_long.py

python 解释器将运行文件 lat_long.py 的内容并打印结果(如果有)。

import pandas as pd
from math import sin, cos, sqrt, atan2, radians

filename = 'lat_long.csv'
df = pd.read_csv(filename)


df['timestamp'] = pd.to_datetime(df['timestamp'], format='%d/%m/%Y %H:%M')


def getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2):
    R = 6371 # Radius of the earth in km
    dLat = radians(lat2-lat1)
    dLon = radians(lon2-lon1)
    rLat1 = radians(lat1)
    rLat2 = radians(lat2)
    a = sin(dLat/2) * sin(dLat/2) + cos(rLat1) * cos(rLat2) * sin(dLon/2) * sin(dLon/2)
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    d = R * c # Distance in km
    return d

def calc_velocity(dist_km, time_start, time_end):
    """Return 0 if time_start == time_end, avoid dividing by 0"""
    return dist_km / (time_end - time_start).seconds if time_end > time_start else 0

# First sort by ID and timestamp:
df = df.sort_values(by=['ID', 'timestamp'])

# Group the sorted dataframe by ID, and grab the initial value for lat, lon, and time.
df['lat0'] = df.groupby('ID')['latitude'].transform(lambda x: x.iat[0])
df['lon0'] = df.groupby('ID')['longitude'].transform(lambda x: x.iat[0])
df['t0'] = df.groupby('ID')['timestamp'].transform(lambda x: x.iat[0])

# create a new column for distance
df['dist_km'] = df.apply(
    lambda row: getDistanceFromLatLonInKm(
        lat1=row['latitude'],
        lon1=row['longitude'],
        lat2=row['lat0'],
        lon2=row['lon0']
    ),
    axis=1
)
print(df)

【讨论】:

绝对天才!非常感谢您竭尽全力帮助我。

以上是关于为啥在定义全局名称时出现错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Xamarin 会在单击按钮时出现错误?

为啥在运行玩笑测试时出现“未定义:x:y:属性”缺失错误?

为啥我在尝试用 110 渲染站点时出现错误?

Redux Form - 渲染以下自定义组件时出现错误?不知道为啥?

使用通用登录视图时出现“名称'django'未定义”错误?

为啥我在将 unique_ptr 返回给模板类的对象的函数定义时出现错误?