Converting all non-numeric to 0 (zero) in Python
我正在寻找将Python中所有非数字数据(包括空格)转换为零的最简单方法。以下列为例:
1 | someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]] |
我希望输出如下:
1 | desiredData = [[1.0,4,7,-50],[0,0,0,12.5644]] |
号
所以"7"应该是7,但"8个香蕉"应该转换为0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import numbers def mapped(x): if isinstance(x,numbers.Number): return x for tpe in (int, float): try: return tpe(x) except ValueError: continue return 0 for sub in someData: sub[:] = map(mapped,sub) print(someData) [[1.0, 4, 7, -50], [0, 0, 0, 12.5644]] |
它适用于不同的数字类型:
1 2 3 4 5 6 7 8 9 10 | In [4]: from decimal import Decimal In [5]: someData = [[1.0,4,'7',-50 ,"99", Decimal("1.5")],["foobar",'8 bananas','text','',12.5644]] In [6]: for sub in someData: ...: sub[:] = map(mapped,sub) ...: In [7]: someData Out[7]: [[1.0, 4, 7, -50, 99, Decimal('1.5')], [0, 0, 0, 0, 12.5644]] |
。
使用正则表达式的另一个解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import re def toNumber(e): if type(e) != str: return e if re.match("^-?\d+?\.\d+?$", e): return float(e) if re.match("^-?\d+?$", e): return int(e) return 0 someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]] someData = [map(toNumber, list) for list in someData] print(someData) |
你会得到:
1 | [[1.0, 4, 7, -50], [0, 0, 0, 12.5644]] |
。
注意,它不适用于科学记数法中的数字。
一条直线:
1 2 3 4 | import re result = [[0 if not re.match("^(\d+(\.\d*)?)$|^(\.\d+)$", str(s)) else float(str(s)) if not str(s).isdigit() else int(str(s)) for s in xs] for xs in somedata] >>> result [[1.0, 4, 7, 0], [0, 0, 0, 12.5644]] |
号
毫不奇怪,python有一种方法来检查某物是否是数字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import collections import numbers def num(x): try: return int(x) except ValueError: try: return float(x) except ValueError: return 0 def zeronize(data): return [zeronize(x) if isinstance(x, collections.Sequence) and not isinstance(x, basestring) else num(x) for x in data] someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]] desiredData = zeronize(someData) |
号
< BR>
1 | desiredData = `[[1, 4, 7, -50], [0, 0, 0, 12]]` |
号
如果有任意深度的嵌套列表,则定义函数。如果使用python 3.x,则将
这个问题和这个问题可能是相关的。还有这个和这个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | lists = [[1.0,4,'7',-50], ['1', 4.0, 'banana', 3,"12.6432"]] nlists = [] for lst in lists: nlst = [] for e in lst: # Check if number can be a float if '.' in str(e): try: n = float(e) except ValueError: n = 0 else: try: n = int(e) except ValueError: n = 0 nlst.append(n) nlists.append(nlst) print(nlists) |
。
考虑到您需要int和float数据类型,您应该尝试以下代码:
1 2 3 4 5 6 7 8 9 10 | desired_data = [] for sub_list in someData: desired_sublist = [] for element in sub_list: try: some_element = eval(element) desired_sublist.append(some_element) except: desired_sublist.append(0) desired_data.append(desired_sublist) |
这可能不是最佳的方法,但它仍然可以完成你要求的工作。
引号中的整数、浮点数和负数很好:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def is_number(s): try: float(s) return True except ValueError: return False def is_int(s): try: int(s) return True except ValueError: return False |
somedata=[[1.0,4,'7'、-50,'12.333'、'90']、['-333.90'、'8 bananas'、'text'、'',12.5644]]
1 2 3 4 5 6 7 8 9 10 11 12 13 | for l in someData: for i, el in enumerate(l): if isinstance(el, str) and not is_number(el): l[i] = 0 elif isinstance(el, str) and is_int(el): l[i] = int(el) elif isinstance(el, str) and is_number(el): l[i] = float(el) print(someData) |
。
输出:
1 | [[1.0, 4, 7, -50, 12.333, -90], [-333.9, 0, 0, 0, 12.5644]] |
。
另外,您可以在嵌套列表理解中使用
1 2 | >>> [[Decimal(i) if (isinstance(i,str) and i.isdigit()) or isinstance(i,(int,float)) else 0 for i in j] for j in someData] [[Decimal('1'), Decimal('4'), Decimal('7'), Decimal('-50')], [0, 0, 0, Decimal('12.56439999999999912461134954')]] |
请注意,
1 2 | >>> Decimal('7')+3 Decimal('10') |
号
我假设您所指的空白是空字符串。因为您要转换所有字符串,不管它们是否包含字符。我们可以简单地检查对象的类型是否是字符串。如果是,我们可以将其转换为整数0。
1 2 3 4 5 6 7 | cleaned_data = [] for array in someData: for item in array: cleaned_data.append(0 if type(item) == str else item) >>>cleaned_data [1.0, 4, 0, -50, 0, 0, 0, 12.5644] |
号