熊猫 >= 0.25
假设所有可拆分列具有相同数量的逗号分隔项,您可以按逗号拆分,然后使用Series.explode https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.explode.html在每列上:
(df.set_index(['order_id', 'order_date'])
.apply(lambda x: x.str.split(',').explode())
.reset_index())
order_id order_date package package_code
0 1 20/5/2018 p1 #111
1 1 20/5/2018 p2 #222
2 1 20/5/2018 p3 #333
3 3 22/5/2018 p4 #444
4 7 23/5/2018 p5 #555
5 7 23/5/2018 p6 #666
Details
将不被触及的列设置为索引,
df.set_index(['order_id', 'order_date'])
package package_code
order_id order_date
1 20/5/2018 p1,p2,p3 #111,#222,#333
3 22/5/2018 p4 #444
7 23/5/2018 p5,p6 #555,#666
下一步是一个两步过程:用逗号分割以获取一列列表,然后调用explode
将列表值分解为各自的行。
_.apply(lambda x: x.str.split(',').explode())
package package_code
order_id order_date
1 20/5/2018 p1 #111
20/5/2018 p2 #222
20/5/2018 p3 #333
3 22/5/2018 p4 #444
7 23/5/2018 p5 #555
23/5/2018 p6 #666
最后,重置索引。
_.reset_index()
order_id order_date package package_code
0 1 20/5/2018 p1 #111
1 1 20/5/2018 p2 #222
2 1 20/5/2018 p3 #333
3 3 22/5/2018 p4 #444
4 7 23/5/2018 p5 #555
5 7 23/5/2018 p6 #666
熊猫
这应该适用于任何数量的这样的列。其本质是一个小小的堆栈拆栈魔法str.split
.
(df.set_index(['order_date', 'order_id'])
.stack()
.str.split(',', expand=True)
.stack()
.unstack(-2)
.reset_index(-1, drop=True)
.reset_index()
)
order_date order_id package package_code
0 20/5/2018 1 p1 #111
1 20/5/2018 1 p2 #222
2 20/5/2018 1 p3 #333
3 22/5/2018 3 p4 #444
4 23/5/2018 7 p5 #555
5 23/5/2018 7 p6 #666
还有另一种高性能替代方案涉及chain
,但是您需要显式链接并重复每一列(对于很多列来说有点问题)。选择最适合您的问题描述的内容,因为没有单一的答案。
Details
首先,将不被触及的列设置为索引。
df.set_index(['order_date', 'order_id'])
package package_code
order_date order_id
20/5/2018 1 p1,p2,p3 #111,#222,#333
22/5/2018 3 p4 #444
23/5/2018 7 p5,p6 #555,#666
Next, stack
行。
_.stack()
order_date order_id
20/5/2018 1 package p1,p2,p3
package_code #111,#222,#333
22/5/2018 3 package p4
package_code #444
23/5/2018 7 package p5,p6
package_code #555,#666
dtype: object
我们现在有一个系列。所以打电话str.split
在逗号上。
_.str.split(',', expand=True)
0 1 2
order_date order_id
20/5/2018 1 package p1 p2 p3
package_code #111 #222 #333
22/5/2018 3 package p4 None None
package_code #444 None None
23/5/2018 7 package p5 p6 None
package_code #555 #666 None
我们需要去掉 NULL 值,所以调用stack
again.
_.stack()
order_date order_id
20/5/2018 1 package 0 p1
1 p2
2 p3
package_code 0 #111
1 #222
2 #333
22/5/2018 3 package 0 p4
package_code 0 #444
23/5/2018 7 package 0 p5
1 p6
package_code 0 #555
1 #666
dtype: object
我们快到了。现在我们希望索引的倒数第二层成为我们的列,因此使用 unstackunstack(-2)
(unstack
在倒数第二层)
_.unstack(-2)
package package_code
order_date order_id
20/5/2018 1 0 p1 #111
1 p2 #222
2 p3 #333
22/5/2018 3 0 p4 #444
23/5/2018 7 0 p5 #555
1 p6 #666
使用摆脱多余的最后一级reset_index
:
_.reset_index(-1, drop=True)
package package_code
order_date order_id
20/5/2018 1 p1 #111
1 p2 #222
1 p3 #333
22/5/2018 3 p4 #444
23/5/2018 7 p5 #555
7 p6 #666
最后,
_.reset_index()
order_date order_id package package_code
0 20/5/2018 1 p1 #111
1 20/5/2018 1 p2 #222
2 20/5/2018 1 p3 #333
3 22/5/2018 3 p4 #444
4 23/5/2018 7 p5 #555
5 23/5/2018 7 p6 #666