Halo Stackoverflowers!

Saya memiliki DataFrame, diperoleh dari Facebook Marketing API, dan saya ingin unnest kolom menjadi beberapa baris.

Ini adalah contoh data yang saya peroleh melalui API:

ad_name      video_play_curve_actions
ad_1         [{'action_type': 'video_view', 'value': [100, 40, 16, 10, 7, 5, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]
ad_2         [{'action_type': 'video_view', 'value': [100, 51, 22, 13, 9, 7, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]

Apa yang saya cari, adalah hasil yang terlihat seperti diilustrasikan di bawah ini

enter image description here

Saya memerlukan loop for untuk ini karena solusinya harus bekerja untuk 100 baris.

Saya telah menambahkan contoh data dan hasil yang diinginkan ke sheet ini: https ://docs.google.com/spreadsheets/d/1jjbtJlfBNZV_wyyAoPY_scyn_jCNFD04XO1-JsztKAg/edit?usp=sharing

Sangat berharap seseorang di sini dapat membantu saya.

Terima kasih sebelumnya

Sunting:

Terima kasih banyak. Sepertinya ada beberapa cara untuk memperbaikinya, tetapi semua solusi termasuk: pandas.explode: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html

Pasti akan menggunakannya ke depan.

Selamat Hari Rabu

1
Sebastian Bjørnsen 21 September 2021, 11:12

3 jawaban

Jawaban Terbaik

Anda mencari pandas.explode: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html, ditambah beberapa pra-pemrosesan yang diperlukan untuk kolom video_play_curve_actions Anda.

import pandas as pd
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--filepath')
    args = parser.parse_args()

    df = pd.read_csv(args.filepath)
    df['video_play_curve_actions'] = df['video_play_curve_actions'].apply(lambda x: eval(x)[0]['value'])
    df_exploded = df.explode('video_play_curve_actions').rename(columns={'video_play_curve_actions': 'value'})
    print(df_exploded.head())

Keluaran:

  ad_name value
0    ad_1   100
0    ad_1    40
0    ad_1    16
0    ad_1    10
0    ad_1     7

Perhatikan bahwa saya menggunakan eval di sini untuk memproses nilai dalam video_play_curve_actions yang tidak selalu dianggap sebagai praktik terbaik. Jika input berisi tanda kutip ganda " alih-alih tanda kutip tunggal ', kita bisa menggunakan json.loads sebagai gantinya.

1
erap129 21 September 2021, 08:27

Gunakan ast.literal_eval untuk mengonversi string menjadi struktur data python (daftar dict di sini) lalu meledak dan mengekstrak kunci 'nilai':

import ast

out = df[['ad_name']].join(
          df['video_play_curve_actions'].apply(ast.literal_eval).explode()
                                        .apply(lambda x: x['value']).explode()
      ).reset_index(drop=True)

Keluaran:

>>> out
    ad_name video_play_curve_actions
0      ad_1                      100
1      ad_1                       40
2      ad_1                       16
3      ad_1                       10
4      ad_1                        7
..      ...                      ...
105    ad_5                        0
106    ad_5                        0
107    ad_5                        0
108    ad_5                        0
109    ad_5                        0

[110 rows x 2 columns]

Catatan: Cara terbaik mungkin menggunakan respons langsung dari Facebook Marketing API daripada memuat data dari file excel.

2
Corralien 21 September 2021, 08:34

Salah satu caranya adalah dengan mengambil nilai video_play_curve_actions Anda menggunakan str.split(), lalu explode():

(
  df.set_index('ad_name')\
        .video_play_curve_actions.str.split('[').str[-1].str[:-3]\
            .str.split(',').explode().str.strip().reset_index()
            )

Cetakan:

    ad_name video_play_curve_actions
0      ad_1                      100
1      ad_1                       40
2      ad_1                       16
3      ad_1                       10
4      ad_1                        7
..      ...                      ...
105    ad_5                        0
106    ad_5                        0
107    ad_5                        0
108    ad_5                        0
109    ad_5                        0
1
sophocles 21 September 2021, 08:40