将数据框中的单列转换为行 | Pandas Facebook 广告

Convert single column in dataframe to rows | Pandas Facebook Ads

你好 Whosebugers!

我有一个 DataFrame,从 Facebook Marketing API 获得,我想 unnest 将一列分成几行。

这是我通过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]}]

我正在寻找的结果如下图所示

为此我需要一个 for 循环,因为该解决方案需要处理 100 多行。

我已将示例数据和所需的输出添加到此 sheet:https://docs.google.com/spreadsheets/d/1jjbtJlfBNZV_wyyAoPY_scyn_jCNFD04XO1-JsztKAg/edit?usp=sharing

真的希望这里有人能帮助我。

提前致谢

编辑:

非常感谢。似乎有多种修复方法,但所有解决方案都包括:pandas.explodehttps://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html

以后肯定会使用它。

周三快乐

您正在寻找 pandas.explodehttps://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html,以及对您的 video_play_curve_actions 列进行的一些必要预处理。

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())

输出:

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

请注意,我在这里使用 eval 来处理 video_play_curve_actions 中的值,这并不总是被认为是最佳做法。如果输入包含双引号 " 而不是单引号 ' 我们可以使用 json.loads 代替。

一种方法是使用 str.split() 获取 video_play_curve_actions 的值,然后 explode():

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

打印:

    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

使用ast.literal_eval将字符串转换为python数据结构(此处为dict列表)然后分解并提取'value'键:

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)

输出:

>>> 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]

注意:最好的方法可能是直接使用来自 Facebook Marketing API 的响应,而不是从 excel 文件加载数据。