Python 在Google BigQuery中将嵌套的JSON字符串展平到不同的列
我在一个BigQuery表中有一列,如下所示Python 在Google BigQuery中将嵌套的JSON字符串展平到不同的列,python,json,pandas,google-bigquery,Python,Json,Pandas,Google Bigquery,我在一个BigQuery表中有一列,如下所示 {"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}} 在GBQ中是否有这样的输出??(基本上将整个柱展平为不同的柱) 比方说 a={“名称”:“名称1”,“上次交付”:{“推送id”:“推送id
{"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}}
在GBQ中是否有这样的输出??(基本上将整个柱展平为不同的柱)
比方说
a={“名称”:“名称1”,“上次交付”:{“推送id”:“推送id1”,
“时间”:“时间1”},“会话id”:“会话id1”,“源”:“SDK”,
“属性”:{“用户ID”:“u1”}
我曾尝试使用json\u normalize(a)在Python中获得所需的输出,但每次尝试都会出现以下错误
有人知道我怎样才能得到我想要的输出吗。我错过了什么吗
任何帮助都将不胜感激 以下示例适用于BigQuery标准SQL
#standardSQL
WITH `project.dataset.table` AS (
SELECT '{"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}}' col
)
SELECT
JSON_EXTRACT_SCALAR(col, '$.name') name,
STRUCT(
JSON_EXTRACT_SCALAR(col, '$.last_delivered.push_id') AS push_id,
JSON_EXTRACT_SCALAR(col, '$.last_delivered.time') AS time
) last_delivered,
JSON_EXTRACT_SCALAR(col, '$.session_id') session_id,
JSON_EXTRACT_SCALAR(col, '$.source') source,
STRUCT(
JSON_EXTRACT_SCALAR(col, '$.properties.UserId') AS UserId
) properties
FROM `project.dataset.table`
并按预期/要求生成结果
Row name last_delivered.push_id last_delivered.time session_id source properties.UserId
1 name1 push_id1 time1 session_id1 SDK u1
我猜测,为什么它不起作用,是因为您的json数据实际上是一个字符串:
from pandas.io.json import json_normalize
a = '''{"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}}'''
df = json_normalize(a)
输出:
AttributeError: 'str' object has no attribute 'values'
print(df.to_string())
last_delivered.push_id last_delivered.time name properties.UserId session_id source
0 push_id1 time1 name1 u1 session_id1 SDK
与:
from pandas.io.json import json_normalize
a = {"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}}
df = json_normalize(a)
输出:
AttributeError: 'str' object has no attribute 'values'
print(df.to_string())
last_delivered.push_id last_delivered.time name properties.UserId session_id source
0 push_id1 time1 name1 u1 session_id1 SDK
如果是这种情况,您可以在规范化之前使用json.loads()
:
import json
from pandas.io.json import json_normalize
a = '''{"name": "name1", "last_delivered": {"push_id": "push_id1", "time": "time1"}, "session_id": "session_id1", "source": "SDK", "properties": {"UserId": "u1"}}'''
data = json.loads(a)
df = json_normalize(data)
我将您的代码复制到Spyder 3.6中,它可以按照您的要求工作:从pandas.io.json导入json_normalize a={“name”:“name1”,“last_delived”:{“push_id”:“push_id1”,“time”:“time1”},“session id”:“session_id1”,“source”:“SDK”,“properties”:{“UserId”:“u1”}b=json_normalize(a)b Out[5]:last_delivered.push_id last_delivered.time。。。会话\u id源0推送\u id 1时间1。。。session_id1 SDK
json_normalize
对我来说很好。我也知道这个解决方案,但我希望列是动态的。假设对于其他行,属性更多,而对于某些行,值更少。我不喜欢这个,因为我觉得它太手工了。好吧,如果什么都不管用的话,这是唯一的解决办法。无论如何,谢谢你:)我已经回答了你现在的问题。如果您有新问题-请将其作为新问题发布,我们将看看是否可以帮助您。同时,至少考虑一下投票的结果。谢谢米哈伊尔。有没有想过在谷歌大查询中是否有可能?…动态扁平化。通常这类事情都是通过您选择的客户端完成的,比如python。如果您希望完全在BQ中完成这项工作,您需要分两步来实现它——首先生成sql文本,然后执行它。我认为这两步方法是可行的——但是由于对bq的json支持有限——这将过于复杂——所以我认为使用客户端方法——是让他的作品变得完美的方法,谢谢伙计!!。。。。但是,我已经缩小了这个问题。假设我们有一个数据框,其中一列有这样的值。loads()只接受单个字符串值。我知道我可以把它保存在for循环中,但问题是数据帧有数百万行……我认为如果我们这样做,将需要很多时间。还有其他的方法吗???我也一直在尝试。只是用10k行测试,保持循环…上帝!这花了大约30分钟。嗯,输出是我所期望的。每天有超过百万行,我想每天都这样做。有了BQ机器的计算能力,我强烈感觉这些机器可以做得更快,只要有可行性。