はじめに

Qiita投稿初めてになります。
孤独なエンジニアをしています。
AWS歴1.5年、pandas歴半年。コードレビュワーがいないので、記法や関数名等は雑多です。
たまにメモと頭の整理に書いていこうと思います。

今回の概要

list付きの深いjsonデータをdataframeに変換して処理をして修正したいjsonの中身を書き換える。
list付きは思ったよりうまい処理をしている記事が見つからなかったので、書き置きます。

こんな奴です。Amaz●nさんとかがよくリクエストで返してきます。

[{"Items":
    [{"id":1,"data":[1,2]},
    {"id":2, "data":[1,1]}],
  "metadata":{"date":"20180101"}},
 {"Items":
    [{"id":1,"data":[1,2]}],
  "metadata":{"date":"20180102"}}
]

やりたくないこと

loopをnestでたくさん使って総なめする

目的

  1. 日付でthresholdを掛けたい
  2. dataでthresholdを掛けたい

やったこと

1. 日付を抜き出す

dataframe型にして、map関数でdateだけを取り出します。
これで日付のソートとデータ欠損日の除外ができます。

import pandas as pd
Response = ... # 上記
df = pd.DataFrame(Response)
def extract_date(json_data):
    return json_data["date"]

df["date"] = df.metadata.map(extract_date)
print(df)
# =>  Items        metadata      date
#  0 {"id":..}    {"time":...}  "20180101"
#  1 {"id":..}    {"time":...}  "20180102"
# 除外する処理は割愛

2. dataでthresholdをかける

2-1:dataを別dataframeに入れる。
ここで既にloopから逃れられず。
2-2: 修正用データと突き合わせる

# 修正用データのload
df_check = pd.read_csv("data.csv")
#    id_replace    a   b        date
# 0           2    1   2  "20180101"

for idx, row in df.iterrows():
    # 2-1 jsonの必要部分を抜き出す
    gdf = pd.DataFrame(json_data.Items["idx"])
    # 頑張って分解する
    gdf = pd.concat([gdf.map(extract_id),gdf.data.apply(pd.Series)])
    gdf.rename({0:"a",1:"b"},inplace=True)

    # 修正したい日付のdf_checkを取り出す
    gdf_check = df_check[df_check['date']==row['date']]

    # 2-2 leftでmergeしてnullを落とすと、修正する部分だけが残る
    gdf_checked = pd.merge(gdf,gdf_check, on=['a','b'], how='left')  # idの修正を探す
    gdf_checked.dropna(inplace=True)  # 必要なindexを使いたいのでdropna
    ## 修正処理データはgdf_checked["id_replace"]に入っているとする
    for in_idx, in_row in gdf_checked.iterrows():
        json_data[idx]["Items"][in_idx]["id"] = in_row["id_replace"]

まとめ

目的に対し、結局2段のネストになってしまったことが悲しいです。
単純にloopすると総なめなので、loopするイテレーション数は減らせた筈です。

ただ、jsonをもう少しうまく扱う方法があると思うのですが、さっぱり分かっていないです。
コメント等でレビューや更なる改善案をいただけると、勉強になります。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.