基础常用:python 从字串中取出数值

前言

在实作时,常常会把所有资讯存成 csv 档做纪录,用 pandas 的 read_csv 读取後,以 DataFrame 的方式浏览,不过这样内容就会是以「字串」的方式来储存,如果需要用到储存的数值时就有点麻烦,所以本篇会介绍一些从字串取出数字的方法。

重点摘录

方法一:number_from_string.get_nums()
方法二:.isdigit()
方法三:re.findall(r'-?\d+\.?\d*', list)

方法介绍

好用的放在前面~

方法一:现成套件 (number_from_string)

使用 number_from_string 当中的 get_nums()
得到的数字直接是数值型态

安装指令:

pip install nums_from_string

范例:

# 载入现成套件
import nums_from_string as nfs

# 使用 get_nums() 函数
string_with_number = '[6, 7, 8, 9, 10, 11, 12, 13, 14]'
number_list = nfs.get_nums(string_with_number)

print('Extracted numbers: ', number_list)
print('Type of item in "number_list": ', type(number_list[0]))

>>> Extracted numbers:  [6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> Type of item in "number_list":  <class 'int'>

方法二:isdigit()

把字串中每个字元拆开,依序用 isdigit() 来判断是不是数字,是的话再看要转换成什麽数值型态 (可以用 int(), flost()),再储存到 list 里面

缺点:
这个方法的问题在於,要依据什麽来分割字串,str.split() 默认设定是根据空格,但如果字串比较复杂这个方法就比较不适合。另外一个直接的问题是,如果以字元为单位来分割的话(如下面范例),非个位数的位数就会被拆开,旧问题就满严重的~

范例:

# 将字串拆开,依序用 isdigit() 来判断是否为数字
string_with_number = '[3, 4, 5, 6, 7, 8]'
number_list = [int(item) for item in string_with_number if item.isdigit()]

print('Extracted numbers: ', number_list)
print('Type of item in "number_list": ', type(number_list[0]))

>>> Extracted numbers:  [3, 4, 5, 6, 7, 8]
>>> Type of item in "number_list":  <class 'int'>

方法三:正规表达式

这个方法我觉得相对麻烦,但如果要筛选的情况比较特别,想要设定一些条件的话,这个方法满值得试试看~

正规表达式简介

正规表达式的基本概念就是:[某个或某类匹配内容] 加上 [设定匹配出现的情况]

一些基本正规表达式的意思如下:
* 表示比对内容可以出现 0 次或多次
? 表示比对内容可以出现 0 或 1 次
+ 表示比对内容至少出现 1 次,没有上限
\ 则是可以粗分成两种来说明:

  1. 让有特殊功能的符号,变成单纯表示字串的符号(例如:. 表示除了 '\n' 之外的任何字元,但是 . 就变成是匹配小数点)
  2. 或者是表示特殊序列(例如:\d 就代表数字 0 到 9)

下面直接来解释参考文献中举的例子:
针对 '-?\d+\.?\d*' 这一串来做个解析,来看为什麽这一串可以帮助我们找到字串中的数字:

  • -?:负号出现0次或1次
  • \d+:0 到 9 至少出现一次
  • \.?\d*:这边表有小数点的情况考虑进去(小数点可以出现 0 次或 0 次),以及後面可以再接数字(数字可以出现 0 次或多次)

参考文献中举的例子:

# 先载入正规表达式的套件 re (Regular Expressions)
import re

# 使用 re.findall()
sentence = 'Extract 100 , 100.45 and 10000 from this string'
s = [float(s) for s in re.findall(r'-?\d+\.?\d*', sentence)]
print(s)

>>> [100.0, 100.45, 10000.0]

谢谢大家看到这边,如果有错误的地方,或是想讨论的,欢迎在下方留言~

References


<<:  将传统 IPX/SPX 网路连接到 IP 网路,最合适的设备为闸道器

>>:  Ruby解题分享--Sqrt(x),二分搜寻演算法。

AWS资料仓储

当有大量资料需要分析处理时, AWS也提供了云端资料仓储分析Redshift. 在 Redshift...

DAY7-PHP和MYSQL(一)

前言: 在昨天的内容中我们大致介绍了什麽是SQL以及一些Mysql的用法,那今天的目标就是要来把资...

远距 Scrum

前言 前两天分享了远距工作的好处与挑战,今天针对应用面来谈谈 Scrum 活动如何在远距工作的情况下...

第 18 集:Bootstrap 客制化 Sass 必备知识(上)

此篇会着重在客制化修改会用到的 sass 基础语法以及观念分为上下两集。 编译 scss 注解有分...

虹语岚访仲夏夜-17(打杂的Allen篇)

感觉经历了一段乱流区,我走到柜台,跟太子点了杯冰咖啡,就在等咖啡的时候,门打开了,看到一个身影,坐到...