[Zad 2] Rozkmina JSONowo Dataframe'owa. Dlaczego praca z JSONem jest trudna?

  • [Zad 2] Rozkmina JSONowo Dataframe'owa. Dlaczego praca z JSONem jest trudna?

    Posted by Marek on 2024-12-13 at 12:39

    Hej, chciałem się z wami podzielić przemyśleniami na żywym organizmie. Pracujemy obecnie w 2 zadaniu, więc chciałem podrzucić “czemu to nie jest łatwe”. Nie pokażę całego rozwiązania, ale chcę załączyć kilka screenów, żebyśmy mogli warsztatowo popracować na naszym “wyzwaniowym case study”.

    JSON vs Dataframe. To nigdy nie było proste.

    A dlaczego? Z powodu różnic w założeniach co do struktury.

    Co do zasady, JSON ma strukturę zagnieżdżoną. To jest jego ogromna zaleta i duże utrapienie jednocześnie.

    Dataframe z kolei, ma co do zasady strukturę tabularyczną. Czyli mamy kolumny, które posiadają swoją nazwę, typ oraz nullable (czy może być null czy nie). Tu nie ma za dużo miejsca na zagnieżdżenia – no bo jak byście narysowali tabelę, która ma zagnieżdżenia?;-).

    Dlatego, gdy mamy JSON o następującym kształcie (prosto z naszego API pogodowego, dla mojej kochanej Łodzi):

    {"current":{"interval":900,"relative_humidity_2m":80,"surface_pressure":1007.9,"temperature_2m":1.7,"time":"2024-12-13T12:00","weather_code":3},"current_units":{"interval":"seconds","relative_humidity_2m":"%","surface_pressure":"hPa","temperature_2m":"°C","time":"iso8601","weather_code":"wmo code"},"elevation":217.0,"generationtime_ms":0.048041343688964844,"latitude":51.781075,"longitude":19.465134,"timezone":"Europe/Warsaw","timezone_abbreviation":"CET","utc_offset_seconds":3600}

    To widzimy, że to jest zbudowane w kilku blokach (dwa duże bloki current i current_units, pokazują konkretne wartości).

    Co zobaczymy, gdy prawidłowo wczytamy JSONa do Dataframe w Sparku, a następnie wywołamy na nim akcję .show() ? (screen nr 1).

    Interesują nas tutaj przede wszystkim kolumny “current” oraz “current_units”, bo to one są problematyczne. Widzimy, że Spark wziął jedynie… same wartości (JSON posiada schemat klucz-wartość)!

    Ale czy na pewno tak jest, że Spark pominął częśc danych?

    Właśnie nie do końca. Żeby to zrobić, należy na dataframe wywołać funkcję “printSchema()”. Pozwoli nam to na pełen obraz struktury DataFrame. Musimy pamiętac, że “show()” to po prostu pewna uproszczona pomoc podczas tworzenia kodu i może pomijać część rzeczy.

    Poniżej to jak wygląda schemat:

    root

    |-- current: struct (nullable = true)

    | |-- interval: long (nullable = true)

    | |-- relative_humidity_2m: long (nullable = true)

    | |-- surface_pressure: double (nullable = true)

    | |-- temperature_2m: double (nullable = true)

    | |-- time: string (nullable = true)

    | |-- weather_code: long (nullable = true)

    |-- current_units: struct (nullable = true)

    | |-- interval: string (nullable = true)

    | |-- relative_humidity_2m: string (nullable = true)

    | |-- surface_pressure: string (nullable = true)

    | |-- temperature_2m: string (nullable = true)

    | |-- time: string (nullable = true)

    | |-- weather_code: string (nullable = true)

    |-- elevation: double (nullable = true)

    |-- generationtime_ms: double (nullable = true)

    |-- latitude: double (nullable = true)

    |-- longitude: double (nullable = true)

    |-- timezone: string (nullable = true)

    |-- timezone_abbreviation: string (nullable = true)

    |-- utc_offset_seconds: long (nullable = true)

    Okazuje się, że spark wewnątrz przechowuje zagnieżdżoną strukturę!

    Aby się do niej dobrać, wystarczy napisać:

    weatherDF.select("current.*").show(false)

    Rezultat jak na drugim screenie:-).

    Liczę, że to pozwoli – na prawdziwym problemie – lepiej poznać struktury z jakimi pracujemy. No i pomoże Wam rozwiązać drugie zadanie! 😀

    • This discussion was modified 1 month, 1 week ago by  Marek.
    Marek replied 1 month, 1 week ago 1 Member · 0 Replies
  • 0 Replies

Sorry, there were no replies found.

Zaloguj się aby odpowiedzieć