如何获取1列值并将其中一些值基于布尔标志列放在新列中?

时间:2018-11-04 18:31:51

标签: python python-3.x pandas dataframe

说我有以下二维数据框

+--------+-------------------+------------+
| Index, | Module/Line Item, | Is Module, |
+--------+-------------------+------------+
| 0,     | Module 1,         | True,      |
|--------|-------------------|------------|
| 1,     | Line Item 1,      | False,     |
|--------|-------------------|------------|
| 2,     | Line Item 2,      | False,     |
|--------|-------------------|------------|
| 3,     | Module 2,         | True,      |
|--------|-------------------|------------|
| 4,     | Line Item 1,      | False,     |
|--------|-------------------|------------|
| 5,     | Line Item 2,      | False      |
+--------+-------------------+------------+

我希望它变成这样:

+----------+-------------+
| Module   | Line Item   |
+----------+-------------+
| Module 1 | Line Item 1 |
|          |-------------|
|          | Line Item 2 |
|----------|-------------|
| Module 2 | Line Item 1 |
|          |-------------|
|          | Line Item 2 |
+----------+-------------+

实现此目标的最佳方法是什么?我尝试了pivot_table和groupby,但是我都无法按照我想要的方式工作。 请注意,模块之间没有固定数量的行项目,名称中也没有模式。 “是模块”列是指示该值是否是模块并且应该进行透视的唯一指示符。旋转后,出现在该模块下方的所有订单项,直到下一个模块都应属于该模块。

How to pivot a dataframe没有回答,因为它从未解释过如何根据另一列中给出的值将列拆分为层次结构。

2 个答案:

答案 0 :(得分:2)

使用where通过向前填充将False的值Is Module替换为loc,将列名重命名,最后将boolean indexing的过滤条件替换为df['Module'] = df['Module/Line Item'].where(df['Is Module']).ffill() df = df.rename(columns={'Module/Line Item':'Line Item'}) df = df.loc[~df['Is Module'], ['Module','Line Item']] print (df) Module Line Item 1 Module 1 Line Item 1 2 Module 1 Line Item 2 4 Module 2 Line Item 1 5 Module 2 Line Item 2 来过滤列的名称:

Module

如果需要,还可以将df['Module'] = df['Module'].mask(df['Module'].duplicated(), '') print (df) Module Line Item 1 Module 1 Line Item 1 2 Line Item 2 4 Module 2 Line Item 1 5 Line Item 2 的重复值替换为空值:

SELECT * FROM XYZ 
WHERE ((value like '%button%') + 
       (value like '%text%') + 
       (value like '%page%') + 
       (value like '%element%')) >= 3

答案 1 :(得分:1)

另一种解决方案,使用groupby

df.groupby(df['Is Module'].cumsum())['Module/Line Item']\
.apply(lambda g: pd.DataFrame({'Module':g.iloc[0],
                               'Line Item': g.iloc[1:].values}))\
.set_index('Module')

            Line Item
Module  
Module 1    Line Item 1
            Line Item 2
Module 2    Line Item 1
            Line Item 2