panda.io.json.json_使用嵌套的json进行规范化

hk8txs48  于 2022-12-30  发布在  其他
关注(0)|答案(3)|浏览(123)

我一直在尝试normalize一个非常嵌套的json文件,我将在后面分析。我所挣扎的是如何深入到一个以上的层次来规范化。
我浏览了pandas.io.json.json_normalize文档,因为它完全按照我的要求工作。
我已经能够规范化它的一部分,现在了解字典是如何工作的,但我仍然不在那里。
下面的代码,我能够得到只有第一级.

import json
import pandas as pd
from pandas.io.json import json_normalize

with open('authors_sample.json') as f:
    d = json.load(f)

raw = json_normalize(d['hits']['hits'])

authors = json_normalize(data = d['hits']['hits'], 
                         record_path = '_source', 
                         meta = ['_id', ['_source', 'journal'], ['_source', 'title'], 
                                 ['_source', 'normalized_venue_name']
                                 ])

我试图用下面的代码“挖掘”到“作者”字典中,但是record_path = ['_source', 'authors']给了我TypeError: string indices must be integers。就我对json_normalize的理解而言,逻辑应该是好的,但是我仍然不太明白如何用dictlist来挖掘一个json。
我甚至经历了这个简单的example

authors = json_normalize(data = d['hits']['hits'], 
                         record_path = ['_source', 'authors'], 
                         meta = ['_id', ['_source', 'journal'], ['_source', 'title'], 
                                 ['_source', 'normalized_venue_name']
                                 ])

下面是json文件的一部分(5条记录)。

{u'_shards': {u'failed': 0, u'successful': 5, u'total': 5},
 u'hits': {u'hits': [{u'_id': u'7CB3F2AD',
    u'_index': u'scibase_listings',
    u'_score': 1.0,
    u'_source': {u'authors': None,
     u'deleted': 0,
     u'description': None,
     u'doi': u'',
     u'is_valid': 1,
     u'issue': None,
     u'journal': u'Physical Review Letters',
     u'link': None,
     u'meta_description': None,
     u'meta_keywords': None,
     u'normalized_venue_name': u'phys rev lett',
     u'pages': None,
     u'parent_keywords': [u'Chromatography',
      u'Quantum mechanics',
      u'Particle physics',
      u'Quantum field theory',
      u'Analytical chemistry',
      u'Quantum chromodynamics',
      u'Physics',
      u'Mass spectrometry',
      u'Chemistry'],
     u'pub_date': u'1987-03-02 00:00:00',
     u'pubtype': None,
     u'rating_avg_weighted': 0,
     u'rating_clarity': 0.0,
     u'rating_clarity_weighted': 0.0,
     u'rating_innovation': 0.0,
     u'rating_innovation_weighted': 0.0,
     u'rating_num_weighted': 0,
     u'rating_reproducability': 0,
     u'rating_reproducibility_weighted': 0.0,
     u'rating_versatility': 0.0,
     u'rating_versatility_weighted': 0.0,
     u'review_count': 0,
     u'tag': [u'mass spectra', u'elementary particles', u'bound states'],
     u'title': u'Evidence for a new meson: A quasinuclear NN-bar bound state',
     u'userAvg': 0.0,
     u'user_id': None,
     u'venue_name': u'Physical Review Letters',
     u'views_count': 0,
     u'volume': None},
    u'_type': u'listing'},
   {u'_id': u'7AF8EBC3',
    u'_index': u'scibase_listings',
    u'_score': 1.0,
    u'_source': {u'authors': [{u'affiliations': [u'Punjabi University'],
       u'author_id': u'780E3459',
       u'author_name': u'munish puri'},
      {u'affiliations': [u'Punjabi University'],
       u'author_id': u'48D92C79',
       u'author_name': u'rajesh dhaliwal'},
      {u'affiliations': [u'Punjabi University'],
       u'author_id': u'7D9BD37C',
       u'author_name': u'r s singh'}],
     u'deleted': 0,
     u'description': None,
     u'doi': u'',
     u'is_valid': 1,
     u'issue': None,
     u'journal': u'Journal of Industrial Microbiology & Biotechnology',
     u'link': None,
     u'meta_description': None,
     u'meta_keywords': None,
     u'normalized_venue_name': u'j ind microbiol biotechnol',
     u'pages': None,
     u'parent_keywords': [u'Nuclear medicine',
      u'Psychology',
      u'Hydrology',
      u'Chromatography',
      u'X-ray crystallography',
      u'Nuclear fusion',
      u'Medicine',
      u'Fluid dynamics',
      u'Thermodynamics',
      u'Physics',
      u'Gas chromatography',
      u'Radiobiology',
      u'Engineering',
      u'Organic chemistry',
      u'High-performance liquid chromatography',
      u'Chemistry',
      u'Organic synthesis',
      u'Psychotherapist'],
     u'pub_date': u'2008-04-04 00:00:00',
     u'pubtype': None,
     u'rating_avg_weighted': 0,
     u'rating_clarity': 0.0,
     u'rating_clarity_weighted': 0.0,
     u'rating_innovation': 0.0,
     u'rating_innovation_weighted': 0.0,
     u'rating_num_weighted': 0,
     u'rating_reproducability': 0,
     u'rating_reproducibility_weighted': 0.0,
     u'rating_versatility': 0.0,
     u'rating_versatility_weighted': 0.0,
     u'review_count': 0,
     u'tag': [u'flow rate',
      u'operant conditioning',
      u'packed bed reactor',
      u'immobilized enzyme',
      u'specific activity'],
     u'title': u'Development of a stable continuous flow immobilized enzyme reactor for the hydrolysis of inulin',
     u'userAvg': 0.0,
     u'user_id': None,
     u'venue_name': u'Journal of Industrial Microbiology & Biotechnology',
     u'views_count': 0,
     u'volume': None},
    u'_type': u'listing'},
   {u'_id': u'7521A721',
    u'_index': u'scibase_listings',
    u'_score': 1.0,
    u'_source': {u'authors': [{u'author_id': u'7FF872BC',
       u'author_name': u'barbara eileen ryan'}],
     u'deleted': 0,
     u'description': None,
     u'doi': u'',
     u'is_valid': 1,
     u'issue': None,
     u'journal': u'The American Historical Review',
     u'link': None,
     u'meta_description': None,
     u'meta_keywords': None,
     u'normalized_venue_name': u'american historical review',
     u'pages': None,
     u'parent_keywords': [u'Social science',
      u'Politics',
      u'Sociology',
      u'Law'],
     u'pub_date': u'1992-01-01 00:00:00',
     u'pubtype': None,
     u'rating_avg_weighted': 0,
     u'rating_clarity': 0.0,
     u'rating_clarity_weighted': 0.0,
     u'rating_innovation': 0.0,
     u'rating_innovation_weighted': 0.0,
     u'rating_num_weighted': 0,
     u'rating_reproducability': 0,
     u'rating_reproducibility_weighted': 0.0,
     u'rating_versatility': 0.0,
     u'rating_versatility_weighted': 0.0,
     u'review_count': 0,
     u'tag': [u'social movements'],
     u'title': u"Feminism and the women's movement : dynamics of change in social movement ideology, and activism",
     u'userAvg': 0.0,
     u'user_id': None,
     u'venue_name': u'The American Historical Review',
     u'views_count': 0,
     u'volume': None},
    u'_type': u'listing'},
   {u'_id': u'7DAEB9A4',
    u'_index': u'scibase_listings',
    u'_score': 1.0,
    u'_source': {u'authors': [{u'author_id': u'0299B8E9',
       u'author_name': u'fraser j harbutt'}],
     u'deleted': 0,
     u'description': None,
     u'doi': u'',
     u'is_valid': 1,
     u'issue': None,
     u'journal': u'The American Historical Review',
     u'link': None,
     u'meta_description': None,
     u'meta_keywords': None,
     u'normalized_venue_name': u'american historical review',
     u'pages': None,
     u'parent_keywords': [u'Superconductivity',
      u'Nuclear fusion',
      u'Geology',
      u'Chemistry',
      u'Metallurgy'],
     u'pub_date': u'1988-01-01 00:00:00',
     u'pubtype': None,
     u'rating_avg_weighted': 0,
     u'rating_clarity': 0.0,
     u'rating_clarity_weighted': 0.0,
     u'rating_innovation': 0.0,
     u'rating_innovation_weighted': 0.0,
     u'rating_num_weighted': 0,
     u'rating_reproducability': 0,
     u'rating_reproducibility_weighted': 0.0,
     u'rating_versatility': 0.0,
     u'rating_versatility_weighted': 0.0,
     u'review_count': 0,
     u'tag': [u'iron'],
     u'title': u'The iron curtain : Churchill, America, and the origins of the Cold War',
     u'userAvg': 0.0,
     u'user_id': None,
     u'venue_name': u'The American Historical Review',
     u'views_count': 0,
     u'volume': None},
    u'_type': u'listing'},
   {u'_id': u'7B3236C5',
    u'_index': u'scibase_listings',
    u'_score': 1.0,
    u'_source': {u'authors': [{u'author_id': u'7DAB7B72',
       u'author_name': u'richard m freeland'}],
     u'deleted': 0,
     u'description': None,
     u'doi': u'',
     u'is_valid': 1,
     u'issue': None,
     u'journal': u'The American Historical Review',
     u'link': None,
     u'meta_description': None,
     u'meta_keywords': None,
     u'normalized_venue_name': u'american historical review',
     u'pages': None,
     u'parent_keywords': [u'Political Science', u'Economics'],
     u'pub_date': u'1985-01-01 00:00:00',
     u'pubtype': None,
     u'rating_avg_weighted': 0,
     u'rating_clarity': 0.0,
     u'rating_clarity_weighted': 0.0,
     u'rating_innovation': 0.0,
     u'rating_innovation_weighted': 0.0,
     u'rating_num_weighted': 0,
     u'rating_reproducability': 0,
     u'rating_reproducibility_weighted': 0.0,
     u'rating_versatility': 0.0,
     u'rating_versatility_weighted': 0.0,
     u'review_count': 0,
     u'tag': [u'foreign policy'],
     u'title': u'The Truman Doctrine and the origins of McCarthyism : foreign policy, domestic politics, and internal security, 1946-1948',
     u'userAvg': 0.0,
     u'user_id': None,
     u'venue_name': u'The American Historical Review',
     u'views_count': 0,
     u'volume': None},
    u'_type': u'listing'}],
  u'max_score': 1.0,
  u'total': 36429433},
 u'timed_out': False,
 u'took': 170}
drnojrws

drnojrws1#

在下面的Pandas例子中,括号是什么意思?是否有一个逻辑可以遵循,以便更深入地使用[]. [...]

result = json_normalize(data, 'counties', ['state', 'shortname', ['info', 'governor']])

['state', 'shortname', ['info', 'governor']]值中的每个字符串或字符串列表都是要包含的元素的路径,* 以及选定行的路径 *。第二个参数json_normalize()参数(record_path,在文档示例中设置为'counties')告诉函数如何从输入数据结构中选择组成输出行的元素,而meta路径添加了更多的元数据,这些元数据将包含在每一行中。如果愿意,可以将它们视为数据库中的表连接。
the US States documentation example的输入在一个列表中有两个字典,这两个字典都有一个counties键,该键引用另一个字典列表:

>>> data = [{'state': 'Florida',
...          'shortname': 'FL',
...         'info': {'governor': 'Rick Scott'},
...         'counties': [{'name': 'Dade', 'population': 12345},
...                      {'name': 'Broward', 'population': 40000},
...                      {'name': 'Palm Beach', 'population': 60000}]},
...         {'state': 'Ohio',
...          'shortname': 'OH',
...          'info': {'governor': 'John Kasich'},
...          'counties': [{'name': 'Summit', 'population': 1234},
...                       {'name': 'Cuyahoga', 'population': 1337}]}]
>>> pprint(data[0]['counties'])
[{'name': 'Dade', 'population': 12345},
 {'name': 'Broward', 'population': 40000},
 {'name': 'Palm Beach', 'population': 60000}]
>>> pprint(data[1]['counties'])
[{'name': 'Summit', 'population': 1234},
 {'name': 'Cuyahoga', 'population': 1337}]

它们之间有5行数据用于输出:

>>> json_normalize(data, 'counties')
         name  population
0        Dade       12345
1     Broward       40000
2  Palm Beach       60000
3      Summit        1234
4    Cuyahoga        1337

然后meta参数命名一些位于counties列表 * 旁边 * 的元素,然后分别合并这些元素。对于那些meta元素,来自第一个data[0]字典的值分别是('Florida', 'FL', 'Rick Scott'),对于data[1],值是('Ohio', 'OH', 'John Kasich')。因此,您可以看到附加到counties行的值来自同一个顶级字典,分别重复了3次和2次:

>>> data[0]['state'], data[0]['shortname'], data[0]['info']['governor']
('Florida', 'FL', 'Rick Scott')
>>> data[1]['state'], data[1]['shortname'], data[1]['info']['governor']
('Ohio', 'OH', 'John Kasich')
>>> json_normalize(data, 'counties', ['state', 'shortname', ['info', 'governor']])
         name  population    state shortname info.governor
0        Dade       12345  Florida        FL    Rick Scott
1     Broward       40000  Florida        FL    Rick Scott
2  Palm Beach       60000  Florida        FL    Rick Scott
3      Summit        1234     Ohio        OH   John Kasich
4    Cuyahoga        1337     Ohio        OH   John Kasich

因此,如果为meta参数传入一个列表,则列表中的每个元素都是一个单独的路径,并且每个单独的路径都标识要添加到输出行中的数据。
在你的JSON例子中,只有几个嵌套列表需要用第一个参数提升,就像'counties'在例子中所做的那样,这个数据结构中唯一的例子就是嵌套的'authors'键;您必须提取每个['_source', 'authors']路径,然后可以从父对象添加其他键来扩充这些行。
然后,第二个meta参数从最外面的对象拉入_id键,后跟嵌套的['_source', 'title']['_source', 'journal']嵌套路径。
record_path参数以authors列表为起点,如下所示:

>>> d['hits']['hits'][0]['_source']['authors']   # this value is None, and is skipped
>>> d['hits']['hits'][1]['_source']['authors']
[{'affiliations': ['Punjabi University'],
  'author_id': '780E3459',
  'author_name': 'munish puri'},
 {'affiliations': ['Punjabi University'],
  'author_id': '48D92C79',
  'author_name': 'rajesh dhaliwal'},
 {'affiliations': ['Punjabi University'],
  'author_id': '7D9BD37C',
  'author_name': 'r s singh'}]
>>> d['hits']['hits'][2]['_source']['authors']
[{'author_id': '7FF872BC',
  'author_name': 'barbara eileen ryan'}]
>>> # etc.

因此会显示以下行:

>>> json_normalize(d['hits']['hits'], ['_source', 'authors'])
           affiliations author_id          author_name
0  [Punjabi University]  780E3459          munish puri
1  [Punjabi University]  48D92C79      rajesh dhaliwal
2  [Punjabi University]  7D9BD37C            r s singh
3                   NaN  7FF872BC  barbara eileen ryan
4                   NaN  0299B8E9     fraser j harbutt
5                   NaN  7DAB7B72   richard m freeland

然后我们可以使用第三个meta参数添加更多列,如_id_source.title_source.journal,使用['_id', ['_source', 'journal'], ['_source', 'title']]

>>> json_normalize(
...     data['hits']['hits'],
...     ['_source', 'authors'],
...     ['_id', ['_source', 'journal'], ['_source', 'title']]
... )
           affiliations author_id          author_name       _id   \
0  [Punjabi University]  780E3459          munish puri  7AF8EBC3  
1  [Punjabi University]  48D92C79      rajesh dhaliwal  7AF8EBC3
2  [Punjabi University]  7D9BD37C            r s singh  7AF8EBC3
3                   NaN  7FF872BC  barbara eileen ryan  7521A721
4                   NaN  0299B8E9     fraser j harbutt  7DAEB9A4
5                   NaN  7DAB7B72   richard m freeland  7B3236C5

                                     _source.journal
0  Journal of Industrial Microbiology & Biotechno...
1  Journal of Industrial Microbiology & Biotechno...
2  Journal of Industrial Microbiology & Biotechno...
3                     The American Historical Review
4                     The American Historical Review
5                     The American Historical Review

                                       _source.title  \
0  Development of a stable continuous flow immobi...
1  Development of a stable continuous flow immobi...
2  Development of a stable continuous flow immobi...
3  Feminism and the women's movement : dynamics o...
4  The iron curtain : Churchill, America, and the...
5  The Truman Doctrine and the origins of McCarth...
nx7onnlm

nx7onnlm2#

您还可以查看库flatten_json,它不要求您像json_normalize那样编写列层次结构:

from flatten_json import flatten

data = d['hits']['hits']
dict_flattened = (flatten(record, '.') for record in data)
df = pd.DataFrame(dict_flattened)
print(df)

参见https://github.com/amirziai/flatten

n6lpvg4x

n6lpvg4x3#

添加到桑德斯评论,更多的上下文可以在这里找到,因为这个函数的创建者有一个中等博客:https://towardsdatascience.com/flattening-json-objects-in-python-f5343c794b10
值得注意的是,panda的json_normalize可以处理大多数json对象,例如数组。flatten_json库要求它是嵌套的dict。然而,您可以通过将数组添加到dict来解决这个要求,如下所示:

flatten({'response':data}, '.')

在这种情况下,flatten_json库实际上会使用一个点标记的计数器来区分重复项。

flatten({
    'response': [
        {'metrics': {'clicks': '0', 'cost_micros': '0', 'impressions': '3'},
         'segments': {'date': '2022-12-01'}},
        {'metrics': {'clicks': '1', 'cost_micros': '609240', 'impressions': '358'},
         'segments': {'date': '2022-12-01'}},
        {'metrics': {'clicks': '0', 'cost_micros': '0', 'impressions': '3'},
         'segments': {'date': '2022-12-02'}},
        {'metrics': {'clicks': '2', 'cost_micros': '40000', 'impressions': '291'},
         'segments': {'date': '2022-12-02'}},
        {'metrics': {'clicks': '0', 'cost_micros': '0', 'impressions': '2'},
         'segments': {'date': '2022-12-03'}},
        {'metrics': {'clicks': '2', 'cost_micros': '337754', 'impressions': '241'},
         'segments': {'date': '2022-12-03'}},
        {'metrics': {'clicks': '0', 'cost_micros': '0', 'impressions': '4'},
         'segments': {'date': '2022-12-04'}},
        {'metrics': {'clicks': '2', 'cost_micros': '757299', 'impressions': '197'},
         'segments': {'date': '2022-12-04'}}
    ]
}, '.')

产生:

{'response.0.metrics.clicks': '0',
 'response.0.metrics.cost_micros': '0',
 'response.0.metrics.impressions': '3',
 'response.0.segments.date': '2022-12-01',
 'response.1.metrics.clicks': '1',
 'response.1.metrics.cost_micros': '609240',
 'response.1.metrics.impressions': '358',
 'response.1.segments.date': '2022-12-01',
 'response.2.metrics.clicks': '0',
 'response.2.metrics.cost_micros': '0',
 'response.2.metrics.impressions': '3',
 'response.2.segments.date': '2022-12-02',
 'response.3.metrics.clicks': '2',
 'response.3.metrics.cost_micros': '40000',
 'response.3.metrics.impressions': '291',
 'response.3.segments.date': '2022-12-02',
 'response.4.metrics.clicks': '0',
 'response.4.metrics.cost_micros': '0',
 'response.4.metrics.impressions': '2',
 'response.4.segments.date': '2022-12-03',
 'response.5.metrics.clicks': '2',
 'response.5.metrics.cost_micros': '337754',
 'response.5.metrics.impressions': '241',
 'response.5.segments.date': '2022-12-03',
 'response.6.metrics.clicks': '0',
 'response.6.metrics.cost_micros': '0',
 'response.6.metrics.impressions': '4',
 'response.6.segments.date': '2022-12-04',
 'response.7.metrics.clicks': '2',
 'response.7.metrics.cost_micros': '757299',
 'response.7.metrics.impressions': '197',
 'response.7.segments.date': '2022-12-04'}

相关问题