当工作 Python 脚本从 Replit 移至本地 TabPy 服务器时,Dataframe 对象不可调用
我编写了一个 Python 脚本,该脚本使用邮政编码调用美国国家海洋和大气管理局 (NOAA) 端点并获取响应中的气象站列表。然后,该脚本将响应转换为 Pandas 数据框。
基于此 Replit ,我相信它已正常运行。数据框似乎已正确打印到控制台,我可以使用断点检查它。
使用此 博客教程 作为指南,我的真正目标是在 Tableau Prep 流程中利用此 Python 脚本。 Tableau Prep 基本上是一个桌面 ETL 工具,类似于 PowerQuery,但有所不同 :)。
我有一个 TabPy 服务器的本地工作实例,其日志似乎也显示了数据框的正确构造(下图)。但是,我收到
TypeError : 'DataFrame' 对象不可调用
。我还提供了 Tableau Prep 界面中出现的相同错误的图像。
任何帮助都将不胜感激。
以下是我的 TabPy 服务器上运行的实际脚本的语法 - 与 Replit 上的脚本相比,只有极少的修改。
import requests;
import pandas as pd;
import json;
zip = '97034'
userToken = 'foobar123'
headerCreds = dict(token = userToken)
url = 'https://www.ncei.noaa.gov/cdo-web/api/v2/stations?&locationid=ZIP:' + zip
global dfWorking
def get_stations_for_zip():
r = requests.get(url, headers = headerCreds)
data = json.loads(r.text)
if 'results' in data:
data = data.get('results')
dfWorking = pd.DataFrame(data)
# Column datatypes as received
# elevation float64
# mindate object
# maxdate object
# latitude float64
# name int64
# datacoverage float64
# id object
# elevationUnit object
# longitude float64
dfWorking = dfWorking.astype({'name': 'str'})
# dfWorking['name'] = dfWorking.index
# defining an index converts back to float64
print(dfWorking)
else:
print('no results object in response')
return dfWorking
# Note: the below prep functions are undefined until they are on a TabPy server
def get_output_schema():
return pd.DataFrame({
'elevation' : prep_decimal(),
'mindate' : prep_string(),
'maxdate' : prep_decimal(),
'latitude' : prep_date(),
'name' : prep_string(),
'datacoverage' : prep_decimal(),
'id' : prep_decimal(),
'name' : prep_string(),
'elevationUnit' : prep_decimal(),
'longitude' : prep_decimal()
});
get_stations_for_zip()
解决方案需要进行两项更改:
-
在 Tableau Prep 界面中,声明函数名称时,我有
get_stations_for_zip()
,但需要不带括号的get_stations_for_zip
-
在我的脚本中,
get_stations_for_zip
函数需要将“df”(代表数据框)作为参数。因此def get_stations_for_zip(df):
。奇怪的是,这个参数从未在函数中使用过,但它是必需的,我引用的 博客 也显示了同样的内容。
以下是 help.tableau.com 文章 在流程中使用 Python 脚本
的引文When you create your script, include a function that specifies a pandas (pd.DataFrame) as an argument of the function. This will call your data from Tableau Prep Builder.
此行是错误的:
execution_result = get_stations_for_zip()(pd.DataFrame(_arg1))
因为
get_stations_for_zip
返回的是 DataFrame,而您将其视为 Python 函数,因此您尝试:
df = get_stations_for_zip()
df(pd.DataFrame(_arg1)) # and error is right here