我有一个数据框df:
codeID
0 4829
1 2348
2 401
3 281
4 Z3995
5 O888
6 v71.9
7 NaN
8 Z863 3
9 9
10 50
我只想提取列codeID的前3位数字。如果前面有任何字母,那么我想忽略该字母。我也想忽略小数点后的数字。如果数字之间有空格,我想忽略空格后面的数字。我想要的是以下内容:
codeID
0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 NaN
8 863
9 009
10 050
我尝试先使用
来分隔字母和数字df[['Let', 'Num']] = df['codeID'].str.extract(r'([A-Za-z]+)([\d\.]+)', expand=True)
,但是对于没有字母的行,其结果为NaN。有人可以建议我如何有效地做到这一点吗?
答案 0 :(得分:2)
您可以直接使用extract,因为它仅提取第一个匹配项,只需在末尾添加zfill即可填充缺少的数字:
_chooseForm.ShowDialog();
if (_chooseForm.DialogResult == DialogResult.OK)
return _chooseForm.SelectedFileName;
else
return null;
输出
result = df.codeID.str.extract(r'(\d{1,3})').squeeze().str.zfill(3)
print(result)
请注意,上面的模式会搜索至少1位数字(例如在您的输入示例中为0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 NaN
8 863
9 009
10 050
Name: 0, dtype: object
的情况下),最多3位数字。
答案 1 :(得分:1)
执行此操作的另一种方法可以使用 lambda和正则表达式:
%%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
希望这可以解决问题!
答案 2 :(得分:0)
我没有使用正则表达式,但体积较大,但还算不错:
df.loc[~df.codeID.isna(), 'codeID'] = df.codeID.dropna().apply(lambda x: x.split(' ')[0])
df.loc[~df.codeID.isna(), 'codeID'] = df.codeID.dropna().apply(lambda x: x.split('.')[0])
df.codeID = df.codeID.str.lstrip('acdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
df.codeID = df.codeID.str.slice(0,3)
df.codeID = df.codeID.str.zfill(3)
df
>
codeID
0 482
1 234
2 401
3 281
4 399
5 888
6 071
7 nan
8 863
9 009
10 050