将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict

Posted

技术标签:

【中文标题】将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict【英文标题】:Formatting Biquery query to ML appropriate JSON to Pass through ML Predict 【发布时间】:2018-04-25 18:33:00 【问题描述】:

使用 Python 2.7,我不会将查询从 BigQuery 传递到具有 specific formating 请求的 ML Predict。

首先:有没有一种更简单的方法可以直接从 BigQuery 查询以正确格式转到 JSON,以便可以将其传递给 requests.post() 而不是通过 pandas(据我所知,GCP 标准仍然不支持 pandas )?

第二:有没有办法构造查询以直接转为 JSON 格式,然后修改 JSON 以反映 ML Predict JSON 要求?

目前我的代码如下所示:

#I used the bigquery to dataframe option here to view the output.
#I would like to not use pandas in the end code.
logs = log_data.execute(output_options=bq.QueryOutput.dataframe()).result()
data = logs.to_json(orient='index')
print data

'"0":"end_time":"2018-04-19","device":"iPad","device_os":"ios","device_os_version":"5.1.1","latency":0.150959,"megacycles":140.0,"cost":"1.3075e-08","device_brand":"Apple","device_family":"iPad","browser_version":"5.1","app":"567","ua_parse":"0"'

#The JSON needs to be in this format according to google documentation.
#data =  
#  'instances': [
#    
#      'key':'',
#      'end_time': '2018-04-19',
#      'device': 'iPad',
#      'device_os': 'iOS',
#      'device_os_version': '5.1.1',
#      'latency': 0.150959,
#      'megacycles':140.0,
#      'cost':'1.3075e-08',
#      'device_brand':'Apple',
#      'device_family':'iPad',
#      'browser_version':'5.1',
#      'app':'567',
#      'ua_parse':'40.9.8'
#    
#  ]
#

所以我只需要更改前导键 '0''instances' 并且我应该准备好传递到 `requests.post()。

有没有办法做到这一点?

编辑-添加 BigQuery 查询:

%%bq query --n log_data
WITH `my.table` AS (
  SELECT ARRAY<STRUCT<end_time STRING, device STRING, device_os STRING, device_os_version STRING, latency FLOAT64, megacycles FLOAT64,
  cost STRING, device_brand STRING, device_family STRING, browser_version STRING, app STRING, ua_parse STRING>>[] instances
)
SELECT TO_JSON_STRING(t)
FROM `my.table` AS t
WHERE end_time >='2018-04-19'
LIMIT 1

data = log_data.execute().result()

感谢@MikhailBerlyant,我已将查询和代码调整为如下所示:

%%bq query --n log_data
SELECT [TO_JSON_STRING(t)] AS instance
FROM `yourproject.yourdataset.yourtable` AS t
WHERE end_time >='2018-04-19'
LIMIT 1

但是当我运行执行 logs = log_data.execute().result() 我得到这个

当传入request.post时会导致这个错误

TypeError: QueryResultsTable job_zfVEiPdf2W6msBlT6bBLgMusF49E is not JSON serializable

execut() 中有没有办法只返回 json?

【问题讨论】:

【参考方案1】:

首先:有没有更简单的方法可以直接从 BigQuery 查询以正确格式转到 JSON

见下例

#standardSQL
WITH yourTable AS (
  SELECT ARRAY<STRUCT<id INT64, type STRING>>[(1, 'abc'), (2, 'xyz')] instances
)
SELECT TO_JSON_STRING(t)
FROM yourTable t 

结果是您要求的格式:

"instances":["id":1,"type":"abc","id":2,"type":"xyz"]  

以上演示了查询及其工作原理 在你的真实情况下 - 你应该使用类似下面的东西

SELECT TO_JSON_STRING(t)
FROM `yourproject.yourdataset.yourtable` AS t
WHERE end_time >='2018-04-19'
LIMIT 1

希望这会有所帮助:o)

基于cmets更新

SELECT [TO_JSON_STRING(t)] AS instance
FROM `yourproject.yourdataset.yourtable` t    
WHERE end_time >='2018-04-19'
LIMIT 1

【讨论】:

我已将我的查询添加到问题中。这看起来正确吗?我收到此错误Exception: invalidQuery: Unrecognized name: end_time at [7:7] 您完全丢失了 my.table 中的数据 - 我只看到架构。而不是这个 - 看起来正确。但您需要添加数据。更好 - 只需使用您的真实表并完全删除整个 WIT Hstatement。我需要它只是为了展示方法。有道理吗? 对不起,我可能会混淆。在查询完成之前,我不会知道数据是什么样的。我最终将使它成为一个函数,用户将选择日期并将其传递给查询,因此我将不知道数据是什么。我可以只使用空括号[] 吗? 完全正确,所以你应该使用类似 - SELECT TO_JSON_STRING(t) FROM fourtopapp.daily_logs.app_logs_data_cleaned_20180419_131416 AS t WHERE end_time >='2018-04-19' LIMIT 1 你不需要定义模式 - 并明确设置数据 - 正如我所说 -0 我这样做只是为了演示查询将如何工作【参考方案2】:

我想添加这个,以防有人遇到与我相同的问题,或者至少在你有查询后坚持下去。

我能够编写一个函数,以 Google ML Predict 希望将其传递到 requests.post() 的方式格式化查询。这很可能是实现此目的的一种可怕方法,但我找不到以正确格式从 BigQuery 直接转到 ML Predict 的方法。

def logs(query):
  client = gcb.Client()
  query_job = client.query(query)
  CSV_COLUMNS ='end_time,device,device_os,device_os_version,latency,megacycles,cost,device_brand,device_family,browser_version,app,ua_parse'.split(',')

  for row in query_job.result():
    var = list(row)
    l1 = dict(zip(CSV_COLUMNS,var))
    l1.update('key':'')
    l2 = 'instances':[l1]
  return l2

【讨论】:

以上是关于将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Biquery 中使用 param.key 值“action”和“label”在两个不同的列中创建报告

如何将对象序列化为查询字符串格式?

ML: 降维算法-LDA

将查询正确格式化为Google表格/天气公式

将多态成员变量实例化为适当的类型

在 C# 中将 Excel 列(或单元格)格式化为文本?