การโหลดและแยกวิเคราะห์ไฟล์ JSON ที่มีออบเจ็กต์ JSON หลายรายการ


101

ฉันพยายามที่จะโหลดและแยกไฟล์ JSON ในPython แต่ฉันติดขัดในการพยายามโหลดไฟล์:

import json
json_data = open('file')
data = json.load(json_data)

ผลตอบแทน:

ValueError: Extra data: line 2 column 1 - line 225116 column 1 (char 232 - 160128774)

ฉันมองไปที่18.2 json- ตัวเข้ารหัสและตัวถอดรหัส JSONในเอกสาร Python แต่มันค่อนข้างน่าท้อใจที่จะอ่านเอกสารที่ดูน่ากลัวนี้

สองสามบรรทัดแรก (ไม่ระบุตัวตนด้วยรายการแบบสุ่ม):

{"votes": {"funny": 2, "useful": 5, "cool": 1}, "user_id": "harveydennis", "name": "Jasmine Graham", "url": "http://example.org/user_details?userid=harveydennis", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 2, "cool": 4}, "user_id": "njohnson", "name": "Zachary Ballard", "url": "https://www.example.com/user_details?userid=njohnson", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 0, "cool": 4}, "user_id": "david06", "name": "Jonathan George", "url": "https://example.com/user_details?userid=david06", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 6, "useful": 5, "cool": 0}, "user_id": "santiagoerika", "name": "Amanda Taylor", "url": "https://www.example.com/user_details?userid=santiagoerika", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 8, "cool": 2}, "user_id": "rodriguezdennis", "name": "Jennifer Roach", "url": "http://www.example.com/user_details?userid=rodriguezdennis", "average_stars": 3.5, "review_count": 12, "type": "user"}

คำตอบ:


224

คุณมีJSON เส้นไฟล์รูปแบบข้อความ คุณต้องแยกวิเคราะห์ไฟล์ทีละบรรทัด:

import json

data = []
with open('file') as f:
    for line in f:
        data.append(json.loads(line))

แต่ละบรรทัดมี JSON ที่ถูกต้อง แต่โดยรวมแล้วไม่ใช่ค่า JSON ที่ถูกต้องเนื่องจากไม่มีรายการระดับบนสุดหรือคำจำกัดความของวัตถุ

โปรดทราบว่าเนื่องจากไฟล์มี JSON ต่อบรรทัดคุณจึงไม่ต้องปวดหัวกับการพยายามแยกวิเคราะห์ทั้งหมดในครั้งเดียวหรือเพื่อหาตัวแยกวิเคราะห์ JSON แบบสตรีมมิ่ง ตอนนี้คุณสามารถเลือกที่จะประมวลผลแต่ละบรรทัดแยกกันก่อนที่จะดำเนินการต่อไปเพื่อประหยัดหน่วยความจำในกระบวนการ คุณอาจไม่ต้องการต่อท้ายผลลัพธ์แต่ละรายการในรายการเดียวแล้วประมวลผลทุกอย่างหากไฟล์ของคุณมีขนาดใหญ่มาก

หากคุณมีไฟล์ที่มีออบเจ็กต์ JSON แต่ละรายการที่มีตัวคั่นอยู่ระหว่างใช้ฉันจะใช้โมดูล 'json' เพื่ออ่านในออบเจ็กต์ JSON ทีละรายการได้อย่างไร เพื่อแยกวิเคราะห์วัตถุแต่ละชิ้นโดยใช้วิธีการบัฟเฟอร์


2
+1 อาจเป็นที่น่าสังเกตว่าหากคุณไม่ต้องการวัตถุทั้งหมดในคราวเดียวการประมวลผลทีละชิ้นอาจเป็นแนวทางที่มีประสิทธิภาพมากกว่า ด้วยวิธีนี้คุณจะไม่ต้องจัดเก็บข้อมูลทั้งหมดในหน่วยความจำ แต่เป็นข้อมูลเพียงชิ้นเดียว
Tadeck

1
@Pi_: คุณจะมีพจนานุกรมดังนั้นเพียงแค่เข้าถึงฟิลด์เป็นกุญแจ:data = json.loads(line); print data[u'votes']
Martijn Pieters

1
@Pi_: พิมพ์ผลลัพธ์ของ json.loads () จากนั้นหรือใช้ดีบักเกอร์เพื่อตรวจสอบ
Martijn Pieters

1
@Pi_: ไม่; อย่าสับสนระหว่างรูปแบบ JSON กับการแทนคำสั่งของ python ตอนนี้คุณกำลังเห็นพจนานุกรม python พร้อมสตริง
Martijn Pieters

1
@ user2441441: ดูคำตอบที่เชื่อมโยงจากโพสต์ที่นี่
Martijn Pieters


4

ที่มีรูปแบบไม่ถูกต้อง คุณมีออบเจ็กต์ JSON หนึ่งรายการต่อบรรทัด แต่ไม่มีอยู่ในโครงสร้างข้อมูลที่ใหญ่กว่า (เช่นอาร์เรย์) คุณจะต้องจัดรูปแบบใหม่เพื่อให้ขึ้นต้นด้วย[และลงท้ายด้วย]เครื่องหมายจุลภาคที่ท้ายแต่ละบรรทัดหรือแยกวิเคราะห์ทีละบรรทัดเป็นพจนานุกรมแยกกัน


20
ด้วยไฟล์ 50MB OP น่าจะดีกว่าในการจัดการกับข้อมูลทีละบรรทัด :-)
Martijn Pieters

11
ไฟล์นั้นมีรูปแบบไม่ถูกต้องหรือไม่นั้นขึ้นอยู่กับมุมมองของคน ๆ หนึ่ง หากตั้งใจให้อยู่ในรูปแบบ "เส้น JSON" ก็ใช้ได้ ดู: jsonlines.org
LS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.