一直试图用panda处理一些数据,但运气不佳。
我有一列数据,非常混乱。它包含代码。每个单元格最多只有两个代码(我认为(。
其中一些代码用/
分割,但第二部分仅包含最后一个破折号(-
(之后的代码的最后一部分(例如,k500-899-200/300表示两个代码:k500-899-200和k500-899-300(
有些只有一个代码。有些具有用&
分隔的代码,另一些具有用#
分隔的代码。有些单元格是空白的。
我希望有一个新的专栏,其中代码是完全写出来的,如果有两个代码而不是一个,用;
分隔。
我所拥有的:
colA
JA01-03-AP-00075 / 00014
JA01-03-AP-00065 / 00013
JA01-03-AP-00089
JA01-05-AP-00089 & JA01-03-AP-08894
JA09-08-BC-88873#JA09-08-BC-88845
JA09-08-BC-88123#
dummy
[blank]
unset
我想要什么
ColA ColB
JA01-03-AP-00075 / 00014 JA01-03-AP-00075 ; JA01-03-AP-00014
JA01-03-AP-00065 / 00013 JA01-03-AP-00065 ; JA01-03-AP-00013
JA01-03-AP-00089 JA01-03-AP-00089
JA01-05-AP-00089 & JA01-03-AP-08894 JA01-05-AP-00089 ; JA01-03-AP-08894
JA09-08-BC-88873 # JA09-08-BC-88845 JA09-08-BC-88873 ; JA09-08-BC-88845
JA09-08-BC-88123# JA09-08-BC-88123
dummy dummy
[blank] [blank]
unset unset
到目前为止,我一直专注于尝试通过/
进行拆分。我的代码有点像这样,尽管它实际上并不起作用,因为我倾向于得到一个";操作数不能一起广播";错误我还没弄清楚为什么。
但我觉得我有点过于复杂了。
def split_code(code):
split_code = code.split('/')
return split_code if len(split_code) == 2 else ['', split_code[0]]
df[['tempCol1', 'tempCol2']] = pd.DataFrame(df['ColA'].apply(split_code).tolist())
df['ColB'] = np.where(df['ColA'].str.contains('/'),
df['tempCol1'].str.rsplit('-', 1)[0] + df['tempCol2'],
df['ColA'])
这是有效的,至少根据您的预期输出:
regex = re.compile(r's*[/&#]s*')
def p(col):
parts = regex.split(col.strip('&#;/'))
if len(parts) > 1:
if parts[1].count('-') <= 1: # short code
parts[1] = f'{"-".join(parts[0].split("-")[0:-1])}-{parts[1]}'
return ' ; '.join(parts)
df['ColB'] = df['ColA'].transform(p)
# match prefix-suffix1 / suffix2
pat = r'(?P<prefix>.+)-(?P<suffix1>d+)s*/s*(?P<suffix2>d+)'
# m is a re.Match object
# prefix-suffix1 / suffix2 => prefix-suffix1 ; prefix-suffix2
def repl_suffix(m):
return f"{m['prefix']}-{m['suffix1']} ; {m['prefix']}-{m['suffix2']}"
df['colB'] = (
df['colA'].str.replace(pat, repl_suffix)
.str.rstrip(r';#&') # strip ';','#','&' from single codes
.str.replace(r's*(#|&)s*',' ; ') # '#' and '&' => ';'
)
>>> df
colA colB
0 JA01-03-AP-00075 / 00014 JA01-03-AP-00075 ; JA01-03-AP-00014
1 JA01-03-AP-00065 / 00013 JA01-03-AP-00065 ; JA01-03-AP-00013
2 JA01-03-AP-00089 JA01-03-AP-00089
3 JA01-05-AP-00089 & JA01-03-AP-08894 JA01-05-AP-00089 ; JA01-03-AP-08894
4 JA09-08-BC-88873#JA09-08-BC-88845 JA09-08-BC-88873 ; JA09-08-BC-88845
5 JA09-08-BC-88123# JA09-08-BC-88123
EDIT:我假设后缀总是数字,但您可以很容易地对任何后缀进行泛化。