Другой способ сделать это можно с помощью лямбда и регулярное выражение :
%%time
df = pd.DataFrame({'CodeID': ['4829','2348','401','281','Z3995', 'O888','v71.9','NaN', 'Z863 3', '9','50']})
print(df['CodeID'].apply(lambda x: 'NaN' if x=='NaN' else re.findall('[0-9]{1,3}', x)[0]).str.zfill(3))
Вывод:
0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 NaN
8 863
9 009
10 050
Name: CodeID, dtype: object
Wall time: 0 ns
Если есть толькоалфавиты в слове, чтобы избежать ошибок, можно использовать следующий код:
1) Для печати 'NaN'
вместо алфавитов:
print(df['CodeID'].apply(lambda x: re.findall('[0-9]{1,3}', x)[0] if re.findall('[0-9]{1,3}', x) else 0).str.zfill(3))
Вывод:
0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 NaN
8 863
9 009
10 050
11 NaN
2) Для печати '000'
вместо алфавитов:
print(df['CodeID'].apply(lambda x: re.findall('[0-9]{1,3}', x)[0] if re.findall('[0-9]{1,3}', x) else '0').str.zfill(3))
Вывод:
0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 000
8 863
9 009
10 050
11 000
Надеюсь, это решит вопрос!