【问题标题】:get_dummies for Pandas column containing list包含列表的 Pandas 列的 get_dummies
【发布时间】:2016-09-19 19:05:04
【问题描述】:

假设我有一个包含字符串列表的列的 DataFrame,如下所示:

    Name    Fruit
0   Curly   [Apple]
1   Moe     [Orange]
2   Larry   [Apple, Banana]

我怎样才能把它变成这样的东西?

    Name     Fruit_Apple   Fruit_Orange   Fruit_Banana
0   Curly              1              0              0
1   Moe                0              1              0
2   Larry              1              0              1

我觉得我会以某种方式使用pandas.get_dummies(),但我似乎无法理解。有什么帮助吗?

【问题讨论】:

    标签: python pandas data-science


    【解决方案1】:
    import pandas as pd
    
    df = pd.DataFrame({'Name': ['Curly', 'Moe', 'Larry'],
                       'Fruit': [['Apple'], ['Orange'], ['Apple', 'Banana']]},
                      columns=['Name', 'Fruit'])
    
    # a one-liner... that's pretty long    
    dummies_df = pd.get_dummies(
      df.join(pd.Series(df['Fruit'].apply(pd.Series).stack().reset_index(1, drop=True),
                        name='Fruit1')).drop('Fruit', axis=1).rename(columns={'Fruit1': 'Fruit'}),
      columns=['Fruit']).groupby('Name', as_index=False).sum()
    
    print(dummies_df)
    

    我将把它分解成几个步骤:

    第 1 步:

    df['Fruit'].apply(pd.Series).stack().reset_index(1, drop=True)

    此步骤将pd.Series 应用于您的列表,将列表中的每个项目拆分为一个新列。 stack 然后将这些列堆叠成一列,同时保留重要的索引信息。 reset_index 部分重置索引的级别 1 并删除它,因为它不需要。你最终会得到这个:

    0     Apple
    1    Orange
    2     Apple
    2    Banana
    dtype: object 
    

    第 2 步:

    您会注意到 pd.Series( *Step 1 here*, name='Fruit1') 包含在上面的第 1 步代码中,因为我们接下来将把这个系列加入到现有的数据帧中,所以我们需要一个 name 才能做到这一点。

    第 3 步:

    df.join(* steps 1 and 2 code *).drop('Fruit', axis=1).rename(columns={'Fruit1': 'Fruit'})
    

    由于我们现在有一个带有名称 (Fruit1) 的 pd.Series,我们将 Fruit1 系列加入到原来的 df 中,该系列有三列。然后我们调用 drop 来删除原来的 Fruit 列。现在我们只有两列 NameFruit1,但我们希望将 Fruit 命名为 Fruit,因此我们将其重命名为 rename

    第 4 步:

    pd.get_dummies(* steps 1, 2, and 3 here*, columns=['Fruit'])
    

    在这里,我们最终调用get_dummies,并使用columns=['Fruit'] 专门告诉get_dummies 只获取Fruit 列的虚拟对象。

        Name  Fruit_Apple  Fruit_Banana  Fruit_Orange
    0  Curly          1.0           0.0           0.0
    1    Moe          0.0           0.0           1.0
    2  Larry          1.0           0.0           0.0
    2  Larry          0.0           1.0           0.0
    

    第 5 步:

    dummies_df = (*steps 1, 2, 3, and 4*).groupby('Name', as_index=False).sum()
    

    最后,您在Name 列上使用groupby 并指定as_index=False 以选择性地不将Name 设置为索引。然后将结果与.sum()相加

    最终结果

        Name  Fruit_Apple  Fruit_Banana  Fruit_Orange
    0  Curly          1.0           0.0           0.0
    1  Larry          1.0           1.0           0.0
    2    Moe          0.0           0.0           1.0
    

    【讨论】:

    • 您可以将第 4 步和第 5 步替换为 pd.crosstab(df_unwind['Name'], df_unwind['Fruit1'])。 df_unwind 是第 3 步之后的 df。不是单行而是更短。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2021-08-11
    • 2021-12-03
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多