有Pandas列包含列表,如何将唯一的列表元素透视到列?

2024-05-16 20:23:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个网络刮板,从产品表中提取信息并构建一个数据框。数据表有一个Description列,其中包含一个逗号分隔的描述产品的属性字符串。我想在dataframe中为每个惟一的属性创建一个列,并用属性的子字符串填充该列中的行。示例df如下。在

PRODUCTS     DATE        DESCRIPTION
Product A    2016-9-12   Steel, Red, High Hardness
Product B    2016-9-11   Blue, Lightweight, Steel
Product C    2016-9-12   Red

我想第一步是把描述分成一个列表。在

^{pr2}$

我想要的输出如下表所示。列名不是特别重要。在

PRODUCTS     DATE        STEEL_COL  RED_COL    HIGH HARDNESS_COL  BLUE COL   LIGHTWEIGHT_COL
Product A    2016-9-12   Steel      Red        High Hardness
Product B    2016-9-11   Steel                                    Blue       Lightweight
Product C    2016-9-12              Red

我相信可以使用一个轴来设置列,但是我不确定在建立这些列之后,最适合python的方式来填充这些列。感谢任何帮助。在

更新

非常感谢你的回答。我选择@MaxU的回答是正确的,因为它看起来更灵活一些,但是@piRSquared的结果非常相似,甚至可以被认为是更具Python式的方法。我测试了两个版本,都做了我需要的。谢谢!在


Tags: 字符串刮板网络date属性产品colblue
3条回答

这是我从一个我已经在研究的问题中延伸出来的解决方案。在

def group_agg_pivot_df(df, group_cols, agg_func='count', agg_col=None):

    if agg_col is None:
        agg_col = group_cols[0]

    grouped = df.groupby(group_cols).agg({agg_col: agg_func}) \
        .unstack().fillna(0)
    # drop aggregation column name from hierarchical column names
    grouped.columns = grouped.columns.droplevel()

    # promote index to column (the first element of group_cols)
    pivot_df = grouped.reset_index()
    pivot_df.columns = [s.replace(' ', '_').lower() for s in pivot_df.columns]
    return pivot_df

def split_stack_df(df, id_cols, split_col, new_col_name):
    # id_cols are the columns we want to pair with the values
    # from the split column

    stacked = df.set_index(id_cols)[split_col].str.split(',', expand=True) \
        .stack().reset_index(level=id_cols)
    stacked.columns = id_cols + [new_col_name]
    return stacked

stacked = split_stack_df(df, ['PRODUCTS', 'DATE'], 'DESCRIPTION', 'desc')
final_df = group_agg_pivot_df(stacked, ['PRODUCTS', 'DATE', 'desc'])

我还将@MaxU、@piRSquared和我的解决方案放在一个有11592行的pandas数据框和一个包含2681个唯一值的列表的列上。显然,列名在测试数据帧中是不同的,但我保持了它们与问题中的相同。在

下面是每种方法的基准

^{pr2}$

1个回路,最好3个:每个回路1.14秒

In [278]: %timeit df.set_index(['PRODUCTS', 'DATE']) \
 ...:     .DESCRIPTION.str.split(',', expand=True) \
 ...:     .stack() \
 ...:     .reset_index() \
 ...:     .pivot_table(index=['PRODUCTS', 'DATE'], columns=0, fill_value=0, aggfunc='size')

1个回路,最好每回路3:612ms

In [286]: %timeit stacked = split_stack_df(df, ['PRODUCTS', 'DATE'], 'DESCRIPTION', 'desc'); \
 ...:     final_df = group_agg_pivot_df(stacked, ['PRODUCTS', 'DATE', 'desc'])

1个回路,最好为3:62.7 ms/回路

我猜聚合和取消堆叠比pivot_table()或警察局的傻瓜(). 在

您可以建立稀疏矩阵:

In [27]: df
Out[27]:
    PRODUCTS       DATE                DESCRIPTION
0  Product A  2016-9-12  Steel, Red, High Hardness
1  Product B  2016-9-11   Blue, Lightweight, Steel
2  Product C  2016-9-12                        Red

In [28]: (df.set_index(['PRODUCTS','DATE'])
   ....:    .DESCRIPTION.str.split(',\s*', expand=True)
   ....:    .stack()
   ....:    .reset_index()
   ....:    .pivot_table(index=['PRODUCTS','DATE'], columns=0, fill_value=0, aggfunc='size')
   ....: )
Out[28]:
0                    Blue  High Hardness  Lightweight  Red  Steel
PRODUCTS  DATE
Product A 2016-9-12     0              1            0    1      1
Product B 2016-9-11     1              0            1    0      1
Product C 2016-9-12     0              0            0    1      0

In [29]: (df.set_index(['PRODUCTS','DATE'])
   ....:    .DESCRIPTION.str.split(',\s*', expand=True)
   ....:    .stack()
   ....:    .reset_index()
   ....:    .pivot_table(index=['PRODUCTS','DATE'], columns=0, fill_value='', aggfunc='size')
   ....: )
Out[29]:
0                   Blue High Hardness Lightweight Red Steel
PRODUCTS  DATE
Product A 2016-9-12                  1               1     1
Product B 2016-9-11    1                         1         1
Product C 2016-9-12                                  1

使用^{}

cols = ['PRODUCTS', 'DATE']
pd.get_dummies(
    df.set_index(cols).DESCRIPTION \
      .str.split(',\s*', expand=True).stack()
).groupby(level=cols).sum().astype(int)

enter image description here

相关问题 更多 >