Python 从多个ID列创建子ID
假设我有一个类似于以下的数据:Python 从多个ID列创建子ID,python,python-3.x,pandas,Python,Python 3.x,Pandas,假设我有一个类似于以下的数据: import pandas as pd d = {'col1': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3], 'col2': [11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 11, 11, 11, 11], 'col3': ['X', 'X', 'Y', 'Y', 'Z', 'Y', 'Y', 'Z', 'Z', 'X', 'Y', 'X', 'Z', 'Z']} df = pd
import pandas as pd
d = {'col1': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3],
'col2': [11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 11, 11, 11, 11],
'col3': ['X', 'X', 'Y', 'Y', 'Z', 'Y', 'Y', 'Z', 'Z', 'X', 'Y', 'X', 'Z', 'Z']}
df = pd.DataFrame(data = d)
print(df)
col1 col2 col3
0 1 11 X
1 1 11 X
2 1 11 Y
3 1 11 Y
4 1 11 Z
5 2 12 Y
6 2 12 Y
7 2 12 Z
8 2 12 Z
9 2 12 X
10 3 11 Y
11 3 11 X
12 3 11 Z
13 3 11 Z
我想为主Id列['col1',col2',col3']的唯一值创建一个['subID']列,如下所示:
col1 col2 col3 subID
0 1 11 X 1
1 1 11 X 1
2 1 11 Y 2
3 1 11 Y 2
4 1 11 Z 3
5 2 12 Y 1
6 2 12 Y 1
7 2 12 Z 2
8 2 12 Z 2
9 2 12 X 3
10 3 11 Y 1
11 3 11 X 2
12 3 11 Z 3
13 3 11 Z 3
我可以通过创建临时文件来实现这一点。使用唯一值['col1'、'col2'、'col3']的dataframe,然后在主dataframe中填充新的['subID']列,但是,鉴于我有一个非常大的数据集,循环/iterrows并不理想,因为它需要大量时间来运行。因此,我希望我能找到一种简单/有效的方法:
df['subID'] = df.groupby(['col1', 'col2', 'col3']).cumcount()+1
请注意,上面这行代码并没有真正产生我想要的东西,只是一个完成这项工作的方法示例。你们知道有没有办法做到这一点吗
非常感谢 看起来这样就可以了
groups = df.groupby(['col1','col2'])
df['subID'] = groups['col3'].shift().fillna(df['col3']) != df['col3']
df['subID'] = (groups['subID'].cumsum() +1).astype(int)
产出
col1 col2 col3 subID
0 1 11 X 1
1 1 11 X 1
2 1 11 Y 2
3 1 11 Y 2
4 1 11 Z 3
5 2 12 Y 1
6 2 12 Y 1
7 2 12 Z 2
8 2 12 Z 2
9 2 12 X 3
10 3 11 Y 1
11 3 11 X 2
12 3 11 Z 3
13 3 11 Z 3
看起来这样就可以了
groups = df.groupby(['col1','col2'])
df['subID'] = groups['col3'].shift().fillna(df['col3']) != df['col3']
df['subID'] = (groups['subID'].cumsum() +1).astype(int)
产出
col1 col2 col3 subID
0 1 11 X 1
1 1 11 X 1
2 1 11 Y 2
3 1 11 Y 2
4 1 11 Z 3
5 2 12 Y 1
6 2 12 Y 1
7 2 12 Z 2
8 2 12 Z 2
9 2 12 X 3
10 3 11 Y 1
11 3 11 X 2
12 3 11 Z 3
13 3 11 Z 3
我们还可以做到:
df['subID']=(df[['col2','col3']].ne(df[['col2','col3']].shift()).any(1)
.groupby(df['col1']).cumsum().astype(int))
我们还可以做到:
df['subID']=(df[['col2','col3']].ne(df[['col2','col3']].shift()).any(1)
.groupby(df['col1']).cumsum().astype(int))
这是一种方式:
df['subID'] = df.assign(dupes=~df.duplicated()).groupby('col1')['dupes'].cumsum().astype(int)
结果:
col1 col2 col3 subID
0 1 11 X 1
1 1 11 X 1
2 1 11 Y 2
3 1 11 Y 2
4 1 11 Z 3
5 2 12 Y 1
6 2 12 Y 1
7 2 12 Z 2
8 2 12 Z 2
9 2 12 X 3
10 3 11 Y 1
11 3 11 X 2
12 3 11 Z 3
13 3 11 Z 3
这是一种方式:
df['subID'] = df.assign(dupes=~df.duplicated()).groupby('col1')['dupes'].cumsum().astype(int)
结果:
col1 col2 col3 subID
0 1 11 X 1
1 1 11 X 1
2 1 11 Y 2
3 1 11 Y 2
4 1 11 Z 3
5 2 12 Y 1
6 2 12 Y 1
7 2 12 Z 2
8 2 12 Z 2
9 2 12 X 3
10 3 11 Y 1
11 3 11 X 2
12 3 11 Z 3
13 3 11 Z 3