Hướng dẫn read nested json file in python - đọc tệp json lồng nhau trong python

Tất cả chúng ta đều là những người dữ liệu ở đây, vì vậy bạn đã biết kịch bản: nó có lẽ xảy ra một lần một ngày, có lẽ 5 hoặc thậm chí nhiều hơn. Có một API bạn đang làm việc cùng, và nó thật tuyệt. Nó chứa tất cả các thông tin bạn đang tìm kiếm, nhưng chỉ có một vấn đề: sự phức tạp của các đối tượng JSON lồng nhau là vô tận, và đột nhiên công việc bạn yêu thích cần phải được giữ lại để lấy dữ liệu mà bạn thực sự muốn, và đó là 5 cấp độ sâu trong một địa ngục json lồng nhau. Không ai cảm thấy giống như một "nhà khoa học" hoặc một "kỹ sư" khi một nửa ngày của họ trở thành xử lý các lỗi giá trị chính.

May mắn thay, chúng tôi viết mã trong Python! (Được rồi, ngôn ngữ không tạo ra nhiều sự khác biệt ở đây. Cảm giác như một cuộc gọi tập hợp vào thời điểm đó).Python! (okay fine, language doesn't make much of a difference here. It felt like a rallying call at the time).

Sử dụng API Google Maps làm ví dụ

Để hình dung vấn đề, chúng ta hãy lấy một ví dụ mà ai đó thực sự có thể muốn sử dụng. & nbsp; Tôi nghĩ API Google Maps là một ứng cử viên tốt để phù hợp với hóa đơn ở đây. Google Maps API is a good candidate to fit the bill here.

Mặc dù Google Maps thực sự là một tập hợp các API, ma trận khoảng cách Google Maps. Ý tưởng là với một cuộc gọi API duy nhất, người dùng có thể tính toán khoảng cách và thời gian di chuyển giữa nguồn gốc và vô số điểm đến. Đó là một API đầy đủ tính năng tuyệt vời, nhưng như bạn có thể tưởng tượng JSON kết quả để tính thời gian đi lại giữa nơi bạn đứng và mọi vị trí trong vũ trụ có thể hiểu được tạo ra một cấu trúc JSON cực kỳ phức tạp.

Nhận được một hương vị của địa ngục json

Thực sự nhanh, đây là một ví dụ về các loại tham số yêu cầu này chấp nhận:

"""Fetch and extract JSON data from Google Maps."""
import requests
from config import API_KEY

def google_maps_distance():
    """Fetch distance between two points."""
    endpoint = "https://maps.googleapis.com/maps/api/distancematrix/json"
    params = {
       'units': 'imperial',
       'key': API_KEY,
       'origins': 'New York City, NY',
       'destinations': 'Philadelphia,PA',
       'transit_mode': 'car'
    }
    r = requests.get(endpoint, params=params)
    return r.json
main.py

Một nguồn gốc, một điểm đến. Phản hồi JSON cho một yêu cầu đơn giản này khá đơn giản:

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
Output của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
3

Đối với mỗi điểm đến, chúng tôi nhận được hai điểm dữ liệu: khoảng cách đi lại và thời lượng ước tính. Nếu chúng ta giả thuyết muốn trích xuất các giá trị đó, việc gõ

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
4 không quá điên rồ. Ý tôi là, nó có phần khủng khiếp và mang đến những suy nghĩ bình thường về tự tử, nhưng không có gì khác thường

Bây giờ chúng ta hãy làm mọi thứ thú vị bằng cách thêm một vài điểm dừng trong chuyến đi của chúng tôi:

...

def google_maps_distance():
    """Fetch distance between two points."""
    endpoint = "https://maps.googleapis.com/maps/api/distancematrix/json"
    params = {
       'units': 'imperial',
       'key': API_KEY,
       'origins': 'New York City, NY',
       'destinations': 'Washington,DC|Philadelphia,PA|Santa Barbara,CA|Miami,FL|Austin,TX|Napa County,CA',
       'transit_mode': 'car'
    }
    r = requests.get(endpoint, params=params)
    return r.json()
main.py

Oh fuuucckkkk:

{
  "destination_addresses": [
    "Washington, DC, USA",
    "Philadelphia, PA, USA",
    "Santa Barbara, CA, USA",
    "Miami, FL, USA",
    "Austin, TX, USA",
    "Napa County, CA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
        "distance": {
          "text": "227 mi",
          "value": 365468
        },
        "duration": {
          "text": "3 hours 54 mins",
          "value": 14064
        },
        "status": "OK"
      },
      {
        "distance": {
          "text": "94.6 mi",
          "value": 152193
        },
        "duration": {
          "text": "1 hour 44 mins",
          "value": 6227
        },
        "status": "OK"
      },
      {
        "distance": {
          "text": "2,878 mi",
          "value": 4632197
        },
        "duration": {
          "text": "1 day 18 hours",
          "value": 151772
        },
        "status": "OK"
      },
      {
        "distance": {
          "text": "1,286 mi",
          "value": 2069031
        },
        "duration": {
          "text": "18 hours 43 mins",
          "value": 67405
        },
        "status": "OK"
      },
      {
        "distance": {
          "text": "1,742 mi",
          "value": 2802972
        },
        "duration": {
          "text": "1 day 2 hours",
          "value": 93070
        },
        "status": "OK"
      },
      {
        "distance": {
          "text": "2,871 mi",
          "value": 4620514
        },
        "duration": {
          "text": "1 day 18 hours",
          "value": 152913
        },
        "status": "OK"
      }
    ]
  }],
  "status": "OK"
}
Output của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
3

Rất nhiều điều đang xảy ra ở đây. Có các đối tượng. Có danh sách. Có danh sách các đối tượng là một phần của một đối tượng. Điều cuối cùng tôi muốn giải quyết là cố gắng phân tích dữ liệu này chỉ để vô tình nhận được một khóa vô dụng: cặp giá trị như "trạng thái": "OK"."status": "OK".

Mã mã đến giải cứu

Giả sử chúng tôi chỉ muốn dữ liệu có thể đọc được từ JSON này, được dán nhãn "văn bản" cho cả khoảng cách và thời lượng. Chúng tôi đã tạo một chức năng dưới đây được đặt tên là

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6 để giúp chúng tôi giải quyết chính vấn đề này. Ý tưởng là
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6 là linh hoạt và bất khả tri, do đó có thể được nhập như một mô -đun vào bất kỳ dự án nào bạn có thể cần.

"""Extract nested values from a JSON tree."""


def json_extract(obj, key):
    """Recursively fetch values from nested JSON."""
    arr = []

    def extract(obj, arr, key):
        """Recursively search for values of key in JSON tree."""
        if isinstance(obj, dict):
            for k, v in obj.items():
                if isinstance(v, (dict, list)):
                    extract(v, arr, key)
                elif k == key:
                    arr.append(v)
        elif isinstance(obj, list):
            for item in obj:
                extract(item, arr, key)
        return arr

    values = extract(obj, arr, key)
    return values
extract.py

Chúng ta cần vượt qua hàm này hai giá trị:

  • Một từ điển Python phức tạp, chẳng hạn như phản hồi chúng tôi phân tích từ
    {
      "destination_addresses": [
        "Philadelphia, PA, USA"
      ],
      "origin_addresses": [
        "New York, NY, USA"
      ],
      "rows": [{
        "elements": [{
          "distance": {
            "text": "94.6 mi",
            "value": 152193
          },
          "duration": {
            "text": "1 hour 44 mins",
            "value": 6227
          },
          "status": "OK"
        }]
      }],
      "status": "OK"
    }
    8.
  • Tên của khóa từ điển chứa các giá trị chúng tôi muốn trích xuất.key containing values we want to extract.
from extract import json_extract

# Find every instance of `name` in a Python dictionary. 
names = json_extract(r.json(), 'name')
print(names)
Output của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6

Bất kể đâu là khóa "văn bản" chính trong JSON, hàm này trả về mọi giá trị cho ví dụ "khóa". Đây là chức năng của chúng tôi trong hành động:"text" lives in the JSON, this function returns every value for the instance of "key." Here's our function in action:

...
from extract import json_extract


def google_maps_distance():
    """Fetch distance between two points."""
    endpoint = "https://maps.googleapis.com/maps/api/distancematrix/json"
    params = {
       'units': 'imperial',
       'key': API_KEY,
       'origins': "New York City,NY",
       'destinations': "Washington,DC|Philadelphia,PA|Santa Barbara,CA|Miami,FL|Austin,TX|Napa Valley,CA",
       'transit_mode': 'car',
    }
   r = requests.get(endpoint, params=params)
   travel_values = json_extract(r.json(), 'text')
   return travel_values
main.py

Chạy chức năng này sẽ dẫn đến đầu ra sau:

['227 mi',
 '3 hours 54 mins',
 '94.6 mi',
 '1 hour 44 mins',
 '2,878 mi',
 '1 day 18 hours',
 '1,286 mi',
 '18 hours 43 mins',
 '1,742 mi',
 '1 day 2 hours',
 '2,871 mi',
 '1 day 18 hours'
 ]
Output của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
3

Oh fiddle tôi Timbers! Bởi vì API của Google xen kẽ giữa khoảng cách và thời lượng chuyến đi, mọi giá trị khác xen kẽ giữa khoảng cách và thời gian (chúng ta có thể tạm dừng để đánh giá cao thiết kế khủng khiếp này không? Có những cách tốt hơn vô cùng để cấu trúc phản hồi này). Không bao giờ sợ, một số Python đơn giản có thể giúp chúng tôi chia danh sách này thành hai danh sách:distance and trip duration, every other value alternates between distance and time (can we pause to appreciate this awful design? There are infinitely better ways to structure this response). Never fear, some simple Python can help us split this list into two lists:

my_values = json_extract(r.json(), 'text')

durations = my_values[1::2]  # Get every even-index value from a list
distances = my_values[2::1]  # Get every odd-index value from a list

print('Durations = ', durations)
print('Distances = ', distances)
Parse mọi giá trị khác.

Điều này sẽ đưa một danh sách của chúng tôi và chia nó thành hai danh sách, xen kẽ giữa chẵn và lẻ:

Durations = [
    '3 hours 54 mins',
    '1 hour 44 mins',
    '1 day 18 hours',
    '18 hours 43 mins',
    '1 day 2 hours',
    '1 day 18 hours'
]
Distances = [
    '94.6 mi',
    '1 hour 44 mins',
    '2,878 mi',
    '1 day 18 hours',
    '1,286 mi',
    '18 hours 43 mins',
    '1,742 mi',
    '1 day 2 hours',
    '2,871 mi',
    '1 day 18 hours'
]
Output

Sáng tạo với danh sách

Một chủ đề phổ biến tôi chạy trong khi trích xuất danh sách các giá trị từ các đối tượng JSON như thế này là danh sách các giá trị tôi trích xuất có liên quan rất nhiều. & nbsp; Trong ví dụ trên, trong mỗi thời gian, chúng tôi có một khoảng cách đi kèm, đó là một cơ sở một-một. Hãy tưởng tượng nếu chúng ta muốn liên kết các giá trị này bằng cách nào đó?

Để sử dụng một ví dụ tốt hơn, gần đây tôi đã sử dụng hàm

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6 của chúng tôi để tìm nạp danh sách tên cột và các loại dữ liệu của chúng từ lược đồ cơ sở dữ liệu. Theo danh sách riêng biệt, dữ liệu trông giống như thế này:

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
0TWO Danh sách liên quan

Rõ ràng hai danh sách này có liên quan trực tiếp; sau này đang mô tả cái trước. Làm thế nào điều này có thể hữu ích? Bằng cách sử dụng phương pháp

...

def google_maps_distance():
    """Fetch distance between two points."""
    endpoint = "https://maps.googleapis.com/maps/api/distancematrix/json"
    params = {
       'units': 'imperial',
       'key': API_KEY,
       'origins': 'New York City, NY',
       'destinations': 'Washington,DC|Philadelphia,PA|Santa Barbara,CA|Miami,FL|Austin,TX|Napa County,CA',
       'transit_mode': 'car'
    }
    r = requests.get(endpoint, params=params)
    return r.json()
2 của Python!

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
1zip Hai danh sách thành một từ điển

Tôi thích nghĩ rằng họ gọi nó là Zip vì nó giống như Zipping Up một dây kéo, trong đó mỗi bên của dây kéo là một danh sách. Điều này xuất ra một từ điển trong đó danh sách 1 đóng vai trò là khóa và liệt kê 2 đóng vai trò là giá trị:

Danh sách
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
2Zed dẫn đến từ điển

Và ở đó bạn có nó folks: Một đoạn mã miễn phí để sao chép và bí mật giả vờ bạn đã viết mãi mãi. Tôi đã ném chức năng lên GitHub Gists, nếu điều đó làm bạn hài lòng.

Đó là tất cả cho ngày hôm nay mọi người! Zip nó lên và zip nó ra. Zippity-do-Da, Buh Bye.

Làm cách nào để đọc một tệp JSON lồng nhau trong Python?

Python đã tích hợp các chức năng dễ dàng nhập các tệp JSON dưới dạng từ điển Python hoặc DataFrame của Pandas. Sử dụng PD. read_json () để tải jsons đơn giản và pd.json_normalize () để tải jsons lồng nhau.pd. json_normalize() to load nested JSONs.

Làm cách nào để đọc nhiều đối tượng JSON trong Python?

Để tải và phân tích tệp JSON với nhiều đối tượng JSON, chúng ta cần tuân theo các bước dưới đây:..
Tạo một danh sách trống có tên JsonList ..
Đọc từng dòng tệp vì mỗi dòng chứa JSON hợp lệ. ....
Chuyển đổi từng đối tượng JSON thành Python dict bằng cách sử dụng JSON. ....
Lưu từ điển này vào một danh sách có tên là result jsonlist ..

Làm cách nào để đọc tệp JSON trong Python?

JSON.LOADS (): Nếu bạn có chuỗi JSON, bạn có thể phân tích nó bằng cách sử dụng json.loads () method.json.loads () không lấy đường dẫn tệp, mà là nội dung tệp làm chuỗi, sử dụng FileObject.Đọc () với json.loads () chúng ta có thể trả về nội dung của tệp.Ví dụ: Ví dụ này hiển thị đọc từ cả tệp chuỗi và JSON.If you have a JSON string, you can parse it by using the json.loads() method.json.loads() does not take the file path, but the file contents as a string, using fileobject.read() with json.loads() we can return the content of the file. Example: This example shows reading from both string and JSON file.

Làm cách nào để xử lý JSON lồng nhau?

Một jsonarray có thể phân tích văn bản từ một chuỗi để tạo ra một đối tượng giống như vector.Chúng ta có thể phân tích một đối tượng JSON lồng nhau bằng phương pháp getString (index) của jsonarray.Đây là một phương pháp tiện lợi cho getjsonstring (index).phương thức getString () và nó trả về một giá trị chuỗi tại vị trí được chỉ định.using the getString(index) method of JSONArray. This is a convenience method for the getJSONString(index). getString() method and it returns a string value at the specified position.