我有一些DataFrame:
df = pd.DataFrame({'columnA': ['apple', 'banana', 'peach', 'pear'], 'columnB': ['XAXappleYBY', 'ZZZbananaRDESWA', 'HDJFpeachIUYTA', 'POIUYpearMNBV']})
columnA columnB
0 apple XAXappleYBY
1 banana ZZZbananaRDESWA
2 peach HDJFpeachIUYTA
3 pear POIUYpearMNBV
我想在columnB
中的字符串上分割columnA
并展开,例如:
columnA columnB left_split right_split
0 apple XaXappleYBY XaX YBY
1 banana ZZZbananaRDESWa ZZZ RDESWa
2 peach HDJFpeachIUYTA HDJF IUYTA
3 pear POIUYpearMNBV POIUY MNBV
我该怎么做?
答案 0 :(得分:2)
使用字符串split
和listcomp并构造数据帧df1
。最后,回到df
cols = ['columnA', 'columnB']
df1 = pd.DataFrame([x.split(pat) for pat, x in zip(*map(df.get, cols))],
columns=['left_split', 'right_split'])
df_final = df.join(df1)
Out[153]:
columnA columnB left_split right_split
0 apple XAXappleYBY XAX YBY
1 banana ZZZbananaRDESWA ZZZ RDESWA
2 peach HDJFpeachIUYTA HDJF IUYTA
3 pear POIUYpearMNBV POIUY MNBV
[x.split(pat) for pat, x in zip(*map(df.get, cols))]
上的说明:
zip(*map(df.get, cols))
只是zip(df.columnA, df.columnB)
的另一种书写方式。在具有许多列的数据框上很方便。使用zip-map
版本只是我的习惯:)
[x.split(pat) for pat, x in zip(*map(df.get, cols))]
Out[198]: [['XAX', 'YBY'], ['ZZZ', 'RDESWA'], ['HDJF', 'IUYTA'], ['POIUY', 'MNB']]
[x.split(pat) for pat, x in zip(df.columnA, df.columnB)]
Out[199]: [['XAX', 'YBY'], ['ZZZ', 'RDESWA'], ['HDJF', 'IUYTA'], ['POIUY', 'MNBV']]
它压缩2列。在列表理解的每次迭代中,它对每一列的对应值进行切片。也就是说,在每次迭代中,它会切片与columnA
和columnB
的每一行相对应的元组。每个元组都被解包到pat
,x
,其中pat
是columnA
的值,而x
是columnB
的值。 x是您要分割的字符串,因此调用x.split(pat)
会将columnB
的每个字符串除以pat
的每个columnA
答案 1 :(得分:2)
IIUC,您可以使用:
regpattern = '|'.join(df['columnA'])
df[['left_split','right_split']]=df['columnB'].str.split(regpattern, expand=True)
print(df)
输出:
columnA columnB left_split right_split
0 apple XAXappleYBY XAX YBY
1 banana ZZZbananaRDESWA ZZZ RDESWA
2 peach HDJFpeachIUYTA HDJF IUYTA
3 pear POIUYpearMNBV POIUY MNBV
答案 2 :(得分:1)
我想,也许可以看看这个简单的表达式:
^([A-Z]*)([a-z]*)([A-Z]*)
import pandas as pd
df = pd.DataFrame({'columnA': ['apple', 'banana', 'peach', 'pear'], 'columnB': [
'XAXappleYBY', 'ZZZbananaRDESWA', 'HDJFpeachIUYTA', 'POIUYpearMNBV']})
df['left_split'] = df['columnB'].str.replace(r'^([A-Z]*)([a-z]*)([A-Z]*)', r'\1')
df['right_split'] = df['columnB'].str.replace(r'^([A-Z]*)([a-z]*)([A-Z]*)', r'\3')
print(df)
columnA columnB left_split right_split
0 apple XAXappleYBY XAX YBY
1 banana ZZZbananaRDESWA ZZZ RDESWA
2 peach HDJFpeachIUYTA HDJF IUYTA
3 pear POIUYpearMNBV POIUY MNBV
如果您想简化/更新/探索表达式,请在regex101.com的右上角进行解释。如果您有兴趣,可以观看匹配的步骤或在this debugger link中进行修改。调试器演示了a RegEx engine如何逐步使用一些示例输入字符串并执行匹配过程的过程。
jex.im可视化正则表达式:
答案 3 :(得分:0)
\d+\s+(?<fruit>\w+)\s+\w+(?<middle>\k<fruit>)\w+
输入是没有第一行(标题)的表,找到已命名的组“ middle”,并根据需要将其替换为空字符。
说明:
\d+\s+
找到前导数字和空格
(?<fruit>\w+)
找到您要用于分割的水果,并将该组命名为“水果”。
w+(?<middle>\k<fruit>)\w+
使用先前命名的“水果”作为匹配条件,并将匹配的组命名为“中间”