开发者问题收集

当工作 Python 脚本从 Replit 移至本地 TabPy 服务器时,Dataframe 对象不可调用

2022-11-23
214

我编写了一个 Python 脚本,该脚本使用邮政编码调用美国国家海洋和大气管理局 (NOAA) 端点并获取响应中的气象站列表。然后,该脚本将响应转换为 Pandas 数据框。

基于此 Replit ,我相信它已正常运行。数据框似乎已正确打印到控制台,我可以使用断点检查它。

使用此 博客教程 作为指南,我的真正目标是在 Tableau Prep 流程中利用此 Python 脚本。 Tableau Prep 基本上是一个桌面 ETL 工具,类似于 PowerQuery,但有所不同 :)。

我有一个 TabPy 服务器的本地工作实例,其日志似乎也显示了数据框的正确构造(下图)。但是,我收到 TypeError : 'DataFrame' 对象不可调用 。我还提供了 Tableau Prep 界面中出现的相同错误的图像。

任何帮助都将不胜感激。

Local Tabpy logs

Tableau Prep Error

以下是我的 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()
2个回答

解决方案需要进行两项更改:

  1. 在 Tableau Prep 界面中,声明函数名称时,我有 get_stations_for_zip() ,但需要不带括号的 get_stations_for_zip

Tableau Prep 界面

  1. 在我的脚本中, 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.

的引文
mxs
2022-11-24

此行是错误的:

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
404pio
2022-11-23