Saya memiliki beberapa json yang sedang dibaca dari file di mana setiap baris terlihat seperti ini:

    {
        "id": "someGuid",
        "data": {
            "id": "someGuid",
            "data": {
                "players": {
                    "player_1": {
                        "id": "player_1",
                        "locationId": "someGuid",
                        "name": "someName",
                        "assets": {
                            "assetId1": {
                                "isActive": true,
                                "playlists": {
                                    "someId1": true,
                                    "someOtherId1": false
                                }
                            },
                            "assetId2": {
                                "isActive": true,
                                "playlists": {
                                    "someId1": true
                                }
                            }
                        }
                    },
                    "player_2": {
                        "id": "player_2",
                        "locationId": "someGuid",
                        "name": "someName",
                        "dict": {
                            "assetId3": {
                                "isActive": true,
                                "playlists": {
                                    "someId1": true,
                                    "someOtherId1": false
                                }
                            },
                            "assetId4": {
                                "isActive": true,
                                "playlists": {
                                    "someId1": true
                                }
                            }
                        }
                    }
                }
            },
            "lastRefreshed": "2020-01-23T19:29:15.6354794Z",
            "expiresAt": "9999-12-31T23:59:59.9999999",
            "dataSourceId": "someId"
        }
    }

Saya mengalami kesulitan mencoba mencari cara menggunakan python atau sql di pyspark di Azure Databricks untuk mengubah json ini menjadi format tabel seperti ini:

+===========+=============+===============+===========+==============+=============+=================+
| Location  | Player_ID   |    Player     | Asset_ID  | Asset_Active | Playlist_ID | Playlist_Status |
+===========+=============+===============+===========+==============+=============+=================+
|  someId   | player_1    | ThisIsAPlayer | anotherId | TRUE         | someOtherId | FALSE           |
+-----------+-------------+---------------+-----------+--------------+-------------+-----------------+

Tantangannya adalah mengubah properti pemain di atas menjadi beberapa baris per lokasi. Sebuah lokasi mungkin memiliki sejumlah pemain dari berbagai id. Saya mungkin tidak akan menanyakan pertanyaan ini jika pemain properti adalah array objek pemain alih-alih kamus, tetapi saya tidak memiliki kendali atas struktur dokumen ini, jadi inilah yang harus saya kerjakan. Ini bukan masalah dalam sesuatu seperti PowerBI, di mana manipulasi data lebih mudah.

Yang terjauh yang bisa saya dapatkan adalah melakukan sesuatu seperti ini:

df = spark.read.json(filePath).select("data.id", "data.lastRefreshed", "data.expiresAt","data.dataSourceId","data.data.players.*")

Tetapi ini menghasilkan kerangka data/tabel yang memperluas semua struct bersarang di bawah pemain ke kolom. Saya telah menjelajahi SO mencari seseorang dengan situasi yang sama, tetapi tidak berhasil.

Bagaimana cara saya meledakkan/memperluas kolom pemain dalam kerangka data ini untuk memisahkan baris?

Di pyspark, saya berurusan dengan Spark 2.4.3

0
Gorlon 12 Maret 2020, 20:04

1 menjawab

Jawaban Terbaik

Anda dapat mencoba from_json berfungsi untuk mengubah kolom/bidang dari StructType menjadi MapType, meledak dan kemudian menemukan bidang yang Anda inginkan. untuk Anda misalnya JSON, Anda perlu melakukan ini beberapa kali:

from pyspark.sql.functions import explode, from_json, to_json, json_tuple, coalesce

df.select(explode(from_json(to_json('data.data.players'),"map<string,string>"))) \
  .select(json_tuple('value', 'locationId', 'id', 'name', 'assets', 'dict').alias('Location', 'Player_ID', 'Player', 'assets', 'dict')) \
  .select('*', explode(from_json(coalesce('assets','dict'),"map<string,struct<isActive:boolean,playlists:string>>"))) \
  .selectExpr(
    'Location',
    'Player_ID',
    'Player', 
    'key as Asset_ID',
    'value.isActive',  
    'explode(from_json(value.playlists, "map<string,string>")) as (Playlist_ID, Playlist_Status)'
  ) \
.show()
+--------+---------+--------+--------+--------+------------+---------------+
|Location|Player_ID|  Player|Asset_ID|isActive| Playlist_ID|Playlist_Status|
+--------+---------+--------+--------+--------+------------+---------------+
|someGuid| player_1|someName|assetId1|    true|     someId1|           true|
|someGuid| player_1|someName|assetId1|    true|someOtherId1|          false|
|someGuid| player_1|someName|assetId2|    true|     someId1|           true|
|someGuid| player_2|someName|assetId3|    true|     someId1|           true|
|someGuid| player_2|someName|assetId3|    true|someOtherId1|          false|
|someGuid| player_2|someName|assetId4|    true|     someId1|           true|
+--------+---------+--------+--------+--------+------------+---------------+
1
jxc 13 Maret 2020, 15:30