Python 将列值划分为节,并将节名称存储在新列中

Python 将列值划分为节,并将节名称存储在新列中,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有一个包含多个产品名称的专栏,如 Contract 0 O.U20 1 O.Z20 2 O.H21 3 O.M21 4 O.U21 5 O.Z21 6 O.H22 7 O.M22 8 S3.U20 9 S3.Z20 10 S6.M26 11 S6.U26 12 S6.Z26 13 S6.H27 14 S9.U26 15 S9.Z26 16 F3.

我有一个包含多个产品名称的专栏,如

      Contract
0      O.U20
1      O.Z20
2      O.H21
3      O.M21
4      O.U21
5      O.Z21
6      O.H22
7      O.M22
8     S3.U20
9     S3.Z20
10    S6.M26
11    S6.U26
12    S6.Z26
13    S6.H27
14    S9.U26
15    S9.Z26
16    F3.U26
17    F3.Z26
18    F3.H27
19    F6.H26
20    F6.M26
21    F6.U26
22    F9.U20
我要做的是根据合同名称分配节名,如

   Contract Sections
0     O.U20      O1
1     O.Z20      O1
2     O.H21      O1
3     O.M21      O1
4     O.U21      O2
5     O.Z21      O2
6     O.H22      O2
7     O.M22      O2
8    S3.U20       S3
9    S3.Z20       S3
10   S6.M26       S6
11   S6.U26       S6
12   S6.Z26       S6
13   S6.H27       S6
14   S9.U26       S9
15   S9.Z26       S9
16   F3.U26       F3
17   F3.Z26       F3
18   F3.H27       F3
19   F6.H26       F6
20   F6.M26       F6
21   F6.U26       F6
22   F9.U20       F9
对于S和F系列,我可以使用此代码实现所需的结果(请告诉我是否有更好的实现方法)

因为它只是匹配分配节名称的字符串。不幸的是,O系列并没有一个数字,所以我不得不将它分成4块,如上图所示

   Contract Sections
0     O.U20      O1
1     O.Z20      O1
2     O.H21      O1
3     O.M21      O1
4     O.U21      O2
5     O.Z21      O2
6     O.H22      O2
7     O.M22      O2
我尝试了以下代码

df.loc[df['Contract'].str.contains('O'),'Sections'] = df.index // 4+1
但这是一个错误

ValueError: could not broadcast input array from shape (23) into shape (8)
我如何才能以更好、更高效的方式实现结果?请注意,这只是一个示例数据,原始数据集有更多类似的值。

将代码更改为

df.loc[df['Contract'].str.contains('O'),'Sections'] = 'O' +((df['Contract'].str.contains('O').cumsum().sub(1)//4) + 1).astype(str)
简化

df.loc[df['Contract'].str.contains('S3'),'Sections'] = 'S3'
df.loc[df['Contract'].str.contains('S6'),'Sections'] = 'S6'
df.loc[df['Contract'].str.contains('S9'),'Sections'] = 'S9'
df.loc[df['Contract'].str.contains('F3'),'Sections'] = 'F3'
df.loc[df['Contract'].str.contains('F6'),'Sections'] = 'F6'
df.loc[df['Contract'].str.contains('F9'),'Sections'] = 'F9'
只需将其替换为以下1行代码:

df['Section'] = df['Contract'].str.split('.').str[0]

工作得很有魅力。谢谢,这不会影响O系列吗?您想要的最终输出只需两行代码即可实现。首先运行我提到的代码,然后运行YOBEN_S的代码。这应该会起作用。但只要在他的代码中将所有位置的“合同”替换为“部分”。如果你需要帮助,请告诉我。如果我能接受两个答案就好了。万分感谢
df['Section'] = df['Contract'].str.split('.').str[0]