Python 如何拆分混合值列?
我收到了一些奇怪格式的数据,我一直试图在互联网上搜索类似的问题,但运气不好,我在翻阅熊猫的文档,但可能我找错了地方 例如,我有一个pandas数据框,如下所示,它应该至少包含以下元素:Python 如何拆分混合值列?,python,pandas,dataframe,Python,Pandas,Dataframe,我收到了一些奇怪格式的数据,我一直试图在互联网上搜索类似的问题,但运气不好,我在翻阅熊猫的文档,但可能我找错了地方 例如,我有一个pandas数据框,如下所示,它应该至少包含以下元素:个人,项目,类型,计数,值。大概是这样的: 0 1 2 3 0 type count value 1 person 1 2 item a 5 5 5 3
个人
,项目
,类型
,计数
,值
。大概是这样的:
0 1 2 3
0 type count value
1 person 1
2 item a 5 5 5
3 person 2
4 item b 9 9 9
5 person 3
6 item a 1 2 3
7 item b 1 2 3
8 item c 1 2 3
9 item d 1 2 3
10 4 8 12
0 1 2 3 4
0 type item count value
1 person 1 6 item a 20 30
2 person 1 7 item d - -
4 person 2 9 item d 80 90
5 person 3 10 item b 40 50
6 person 3 11 item a 10 20
8 person 4 7 item c 50 60
其中第一列包含属于该人员的人员姓名
和项目
,该人员应位于其自己的列中。每个人可以有一个或多个项目
我需要找到一种方法,通过将人名移动到每个项目
行来清理这一问题,最终结果如下所示:
0 1 2 3 4
0 name item type count value
1 person 1 item a 5 5 5
2 person 2 item b 9 9 9
3 person 3 item a 1 2 3
4 person 3 item b 1 2 3
5 person 3 item c 1 2 3
6 person 3 item d 1 2 3
0 1 2 3
0 type and item count value
1 person 1 6 item a 20 30
2 7 item d - -
3 20 30
4 person 2 9 item d 80 90
5 person 3 10 item b 40 50
6 11 item a 10 20
7 50 70
8 person 4 7 item c 50 60
我可以通过在每一行上循环,检查type、count、value是否为空来获取人名,然后将其附加到下面的每一行,直到下一行的type、count、value为空,来解决这个问题,但这真的是唯一的解决方案吗,还是有更灵活的方法
另一种格式是这样的:
0 1 2 3 4
0 name item type count value
1 person 1 item a 5 5 5
2 person 2 item b 9 9 9
3 person 3 item a 1 2 3
4 person 3 item b 1 2 3
5 person 3 item c 1 2 3
6 person 3 item d 1 2 3
0 1 2 3
0 type and item count value
1 person 1 6 item a 20 30
2 7 item d - -
3 20 30
4 person 2 9 item d 80 90
5 person 3 10 item b 40 50
6 11 item a 10 20
7 50 70
8 person 4 7 item c 50 60
需要一个解决方案来获得如下输出:
0 1 2 3
0 type count value
1 person 1
2 item a 5 5 5
3 person 2
4 item b 9 9 9
5 person 3
6 item a 1 2 3
7 item b 1 2 3
8 item c 1 2 3
9 item d 1 2 3
10 4 8 12
0 1 2 3 4
0 type item count value
1 person 1 6 item a 20 30
2 person 1 7 item d - -
4 person 2 9 item d 80 90
5 person 3 10 item b 40 50
6 person 3 11 item a 10 20
8 person 4 7 item c 50 60
我的想法是使用一些数据帧模式,但我不认为存在这样的情况?是否有更灵活的解决方案,这意味着我可以向pandas传递几个简单的参数,它将知道如何分别标记个人和项目,或者唯一的解决方案是使用循环和执行if/else来解决它 为方便起见,我在示例中介绍了数据帧:
data = pd.DataFrame([
['', 'type', 'count', 'value'],
['person 1', '', '', ''],
['item a', '5', '5', '5'],
['person 2', '', '', ''],
['item b', '9', '9', '9'],
['person 3', '', '', ''],
['item a', '1', '2', '3'],
['item b', '1', '2', '3'],
['item c', '1', '2', '3'],
['item d', '1', '2', '3'],
['', '4', '8', '12'],
])
data2 = pd.DataFrame([
['', 'type and item', 'count', 'value'],
['person 1', '6 item a', '20', '30'],
['', '7 item d', '-', '-'],
['', '', '20', '30'],
['person 2', '9 item d', '80', '90'],
['person 3', '10 item b', '40', '50'],
['', '11 item a', '10', '20'],
['', '', '50', '70'],
['person 4', '7 item c', '50', '60'],
])
获取数据
data[4]=data[0].where(data[1].eq('')).ffill()
data=data[data[0]!=data[4]]
data=data[data[0]!='']
data
0 1 2 3 4
2 item a 5 5 5 person 1
4 item b 9 9 9 person 2
6 item a 1 2 3 person 3
7 item b 1 2 3 person 3
8 item c 1 2 3 person 3
9 item d 1 2 3 person 3
数据2
data2=data2.join(data2[1].str.split(' ',n=1,expand=True),rsuffix='add')
data2=data2.dropna(subset=['1add'],axis=0)
data2['0']=data2['0'].mask(data2['0'].eq('')).ffill()
data2
0 1 2 3 0add 1add
0 NaN type and item count value type and item
1 person 1 6 item a 20 30 6 item a
2 person 1 7 item d - - 7 item d
4 person 2 9 item d 80 90 9 item d
5 person 3 10 item b 40 50 10 item b
6 person 3 11 item a 10 20 11 item a
8 person 4 7 item c 50 60 7 item c
谢谢你的快速回复,我很抱歉没有澄清。问题是,我得到的人名和项目行实际上并没有那么干净(人名1/人名2),它们通常是真名(Bob、Gary、Patric),并且无法知道是否实际是人名或项目名来按值筛选。@rain01更新为
data[4]=data[0]。其中(data[1]。eq(“”)).ffill()