واجهات API و JSON المتداخل
ردود الواجهات متداخلة؛ كيف نسطّحها إلى جداول بعمودٍ لكل حقل؟ ⏱ نحو 40 دقيقة.
- تدرك أن بيانات الواجهات متداخلة.
- تسطّح الكائنات المتداخلة بـ
json_normalize. - تفرد القوائم الداخلية بـ
record_path. - تحمل حقول المستوى الأعلى بـ
meta.
١بيانات الواجهات ليست مسطّحة
واجهات الويب تردّ JSON متداخلًا: كائن داخل كائن، وقوائم داخل حقول. read_json يعجز عن تسطيحه. الأداة هي pd.json_normalize: تفتح المستويات المتداخلة إلى أعمدة مسطّحة.
٢تسطيح كائن متداخل
import pandas as pdimport json data = json.loads('''[ {"id": 1, "user": {"name": "سارة", "city": "الرياض"}, "total": 300}, {"id": 2, "user": {"name": "خالد", "city": "جدة"}, "total": 150}]''') df = pd.json_normalize(data)print(df)print("الأعمدة:", list(df.columns))
صار user.name وuser.city عمودين مستقلّين. النقطة في الاسم تدلّ على المستوى الذي جاء منه الحقل.
٣قائمة داخل الحقل: record_path
حين يحوي السجلّ قائمةً (كطلبات عميل)، نفرد كل عنصر صفًّا بـ record_path، ونحمل معه حقولًا من الأعلى بـ meta:
import pandas as pdimport json data = json.loads('''[ {"user": "سارة", "orders": [{"item": "سماعة", "qty": 2}, {"item": "كاميرا", "qty": 1}]}, {"user": "خالد", "orders": [{"item": "لوحة", "qty": 3}]}]''') df = pd.json_normalize(data, record_path="orders", meta="user")print(df)print("إجمالي القطع:", df["qty"].sum())
توقّع وتحقّق
لتسطيح JSON متداخل إلى جدول:
user.name في عمود يعني أن name جاء من:
لفرد قائمة داخلية صفوفًا نستخدم:
لحمل حقول من المستوى الأعلى مع الفرد:
الخلاصة
- ردّ الواجهة
JSONمتداخل؛read_jsonلا يسطّحه، وjson_normalizeيفعل. - الكائن المتداخل يصير أعمدةً بأسماء منقّطة مثل
user.city. record_pathيفرد القائمة الداخلية صفوفًا، وmetaيحمل حقول الأعلى.- بهذا نحوّل أي ردّ
APIإلى جدولٍ مسطّح جاهز للتحليل.
تحدٍّ برمجي: سطّح ردّ واجهة
متوسطسطّح بيانات الواجهة المتداخلة، واطبع عدد الصفوف الناتجة، ومجموع amount.
- استخدم
json_normalizeمعrecord_pathوmeta. - اطبع عدد الصفوف ثم مجموع
amount.
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
import pandas as pdimport jsondata = json.loads('''[ {"city": "الرياض", "sales": [{"amount": 300}, {"amount": 120}]}, {"city": "جدة", "sales": [{"amount": 200}]}]''')# سطّح sales واحمل city، ثم اطبع عدد الصفوف ومجموع amount
💡 تلميح 1
pd.json_normalize(data, record_path="sales", meta="city").💡 تلميح 2
len(df) وdf["amount"].sum().حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import pandas as pdimport jsondata = json.loads('''[ {"city": "الرياض", "sales": [{"amount": 300}, {"amount": 120}]}, {"city": "جدة", "sales": [{"amount": 200}]}]''')df = pd.json_normalize(data, record_path="sales", meta="city")print(len(df))print(int(df["amount"].sum()))