我正在尝试从列表中所有列中提取数字值,无论该值是在任何字符的右侧,左侧还是中间。
我有一个如下所示的数据框:
df = pd.DataFrame({
'A': ['1', 3, "1", "cad -2", 3, 4.876, np.nan],
'B': ['116', 'CAD -2.6399', 'CAD -3', '4 $', '$5%', 'A', '-1.2 2']
})
df
我尝试了以下代码,但它正在删除-从“ A”列第4行和“ B”列第3行
l = ["A", "B"]
for columns in l:
if isinstance(df[columns], object):
df[columns] = df[columns].astype('str').str.extract("([-+]?\d*\.\d+|\d+)").astype(float)
df
我希望我的最终数据框如下所示:
A B
1 116
3 -2.6399
1 -3
-2 4
3 5
4.876 NaN
NaN -1.2
答案 0 :(得分:2)
尝试使用str.extract()和正则表达式查找float,如下所示:
df['B'] = df['B'].str.extract("([-+]?\d*\.\d+|[-+]?\d+)").astype(float)
注意:0个匹配项将返回np.nan,而2个以上匹配项将返回第一个匹配项!
完整示例:
import pandas as pd
df = pd.DataFrame({
'A': [1, 3, 1, 2, 3, 4, 2],
'B': ['116', 'CAD 2.6399', 'CAD 3', '4 $', '$5%', 'A', '1.2 2']
})
df['B'] = df['B'].str.extract("([-+]?\d*\.\d+|[-+]?\d+)").astype(float)
print(df)
返回:
A B
0 1 116.0000
1 3 2.6399
2 1 3.0000
3 2 4.0000
4 3 5.0000
5 4 NaN
6 2 1.2000
更新:您可以将其用于多个对象列:
for column in [i for i in df.columns if df[i].dtype == 'object']:
df[column] = df[column].astype(str).str.extract("([-+]?\d*\.\d+|[-+]?\d+)").astype(float)
基于此答案中发现的正则表达式:How to extract a floating number from a string
答案 1 :(得分:0)
尝试一下:
def get_first_nbr_from_str(input_str):
'''
:param input_str: strings that contains digit and words
:return: the number extracted from the input_str
demo:
'ab324.23.123xyz': 324.23
'.5abc44': 0.5
'''
if not input_str and not isinstance(input_str, str):
return 0
out_number = ''
for ele in input_str:
if (ele == '.' and '.' not in out_number) or ele.isdigit():
out_number += ele
elif out_number:
break
return float(out_number)
然后:
df['B'].apply(get_first_nbr_from_str)