说我有以下二维数据框
+--------+-------------------+------------+
| 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没有回答,因为它从未解释过如何根据另一列中给出的值将列拆分为层次结构。
答案 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