私はそうのような構造のファイルの非常に迷惑なセットを持っている:スパーク/ハイブ - 「ピボットテーブル」形式にグループのデータ
userId string,
eventType string,
source string,
errorCode string,
startDate timestamp,
endDate timestamp
各ファイルは様々で、イベントIDあたりのレコードの任意の数を含むことができeventTypesとsources、およびそれぞれ異なるコードと開始日と終了日を指定します。
これらのすべてをuserIdにグループ化する方法はありますか?キー値のようなものです。値はuserIdに関連付けられたすべてのフィールドのリストですか?具体的には、eventTypeとsourceをキーにしたいと思っています。基本的には、ピボットテーブルのような幅のテーブルの長さを交換したいと思っています。このための私の目標は、将来的にはより迅速な分析のために、最終的にApache ParquetまたはAvroファイル形式として保存されることです。
ここでは例です:
ソースデータ:
userId, eventType, source, errorCode, startDate, endDate
552113, 'ACK', 'PROVIDER', 0, '2017-09-01 12:01:45.432', '2017-09-01 12:01:45.452'
284723, 'ACK', 'PROVIDER', 0, '2017-09-01 12:01:45.675', '2017-09-01 12:01:45.775'
552113, 'TRADE', 'MERCH', 0, '2017-09-01 12:01:47.221', '2017-09-01 12:01:46.229'
552113, 'CHARGE', 'MERCH', 0, '2017-09-01 12:01:48.123', '2017-09-01 12:01:48.976'
284723, 'REFUND', 'MERCH', 1, '2017-09-01 12:01:48.275', '2017-09-01 12:01:48.947'
552113, 'CLOSE', 'PROVIDER', 0, '2017-09-01 12:01:49.908', '2017-09-01 12:01:50.623'
284723, 'CLOSE', 'PROVIDER', 0, '2017-09-01 12:01:50.112', '2017-09-01 12:01:50.777'
目標:
userId, eventTypeAckProvider, sourceAckProvider, errorCodeAckProvider, startDateAckProvider, endDateAckProvider, eventTypeTradeMerch, sourceTradeMerch, errorCodeTradeMerch, startDateTradeMerch, endDateTradeMerch, eventTypeChargeMerch, sourceChargeMerch, errorCodeChargeMerch, startDateChargeMerch, endDateChargeMerch, eventTypeCloseProvider, sourceCloseProvider, errorCodeCloseProvider, startDateCloseProvider, endDateCloseProvider, eventTypeRefundMerch, sourceRefundMerch, errorCodeRefundMerch, startDateRefundMerch, endDateRefundMerch
552113, 'ACK', 'PROVIDER', 0, '2017-09-01 12:01:45.432', '2017-09-01 12:01:45.452', 'TRADE', 'MERCH', 0, '2017-09-01 12:01:47.221', '2017-09-01 12:01:46.229', 'CHARGE', 'MERCH', 0, '2017-09-01 12:01:48.123', '2017-09-01 12:01:48.976', 'CLOSE', 'PROVIDER', 0, '2017-09-01 12:01:49.908', '2017-09-01 12:01:50.623', NULL, NULL, NULL, NULL, NULL
284723, 'ACK', 'PROVIDER', 0, '2017-09-01 12:01:45.675', '2017-09-01 12:01:45.775', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'CLOSE', 'PROVIDER', 0, '2017-09-01 12:01:50.112', '2017-09-01 12:01:50.777', 'REFUND', 'MERCH', 1, '2017-09-01 12:01:48.275', '2017-09-01 12:01:48.947'
フィールド名または順序限り、私はそれらを区別することができますよう、問題ではありません。私はすでにこれを動作させるために二つの方法を試してみた
:
- は手動でテーブルからそれぞれの組み合わせを選択して、マスターデータセットに参加します。これはうまく動作し、よくパラレル化されますが、キーフィールドの値の任意の数を許可せず、スキーマを事前定義する必要があります。
- キーの辞書を作成するには、Sparkを使用します。valueレコード各値は辞書です。基本的にデータセットをループし、存在しない場合は辞書に新しいキーを追加し、そのエントリに対して、存在しない場合は新しいフィールドを値辞書に追加します。これは美しく動作しますが、非常に遅く、まったく動作しないとうまく並列化されません。また、それがAvro/Parquet互換フォーマットであるかどうかはわかりません。
これらの2つの方法の代替方法はありますか?または私の目標よりも優れた構造ですか?
おかげでこれを試してみて、自分の意見を与えることができます!これはうまくいくようです!私はライブデータセットで試してみましたが、グループ化の方法に関しては、私が望むものをかなり返しています。しかし、私は "地図のリスト"のデータ構造に精通しておらず、操作のどこにでも記載されたものは何も見つかりません。私は、どのように私はこのデータ構造と対話するのでしょうか?たとえば、特定のユーザーのCHARGE/MERCH属性を取得するにはどうすればよいですか? –
助けてくれてうれしい!これは、フォローアップの質問を開始するのに役立つと思います: 'itertools import chainから; new_df.printSchema();rdd1 = new_df.where(col( 'userId')== '552113')select( 'event_detail')。rdd.flatMap(lambda x:chain(*(x))); keys = rdd1.map(ラムダx:x.keys())。 values = rdd1.map(lambda x:x.values())。collect(); '' keys'と 'values'は調べる必要のあるものです。 – Prem