在 Python 中将所有非数字转换为 0(零)

Posted

技术标签:

【中文标题】在 Python 中将所有非数字转换为 0(零)【英文标题】:Converting all non-numeric to 0 (zero) in Python 【发布时间】:2015-12-17 07:01:07 【问题描述】:

我正在寻找将 Python 中的所有非数字数据(包括空格)转换为零的最简单方法。举个例子:

someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]]

我希望输出如下:

desiredData = [[1.0,4,7,-50],[0,0,0,12.5644]]

所以“7”应该是 7,但“8香蕉”应该转换为 0。

【问题讨论】:

对于你不希望类型改变的数字类型,我的意思是像 int 转换为 float 或反之亦然,如果你的目标是单一类型(而不是数字类型)会更容易) . 【参考方案1】:

使用正则表达式的另一种解决方案

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.0, 4, 7, -50], [0, 0, 0, 12.5644]]

注意它不适用于科学计数法中的数字

【讨论】:

【参考方案2】:

单行:

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]]

【讨论】:

【参考方案3】:

引号中的整数、浮点数和负数都可以:

 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 个香蕉','text','',12.5644]]

 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.0, 4, 7, -50, 12.333, -90], [-333.9, 0, 0, 0, 12.5644]]

【讨论】:

我喜欢这种方法的简单性,但它会将 '7' 转换为 0 而不是 7。 @user1882017,谢谢我错过了'7 ...添加了isdigit(0)检查【参考方案4】:

作为替代方案,您可以在嵌套列表理解中使用 decimal 模块:

>>> [[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')]]

请注意,Decimal 的优势在于,在第一个条件下,您可以使用它为数字字符串获取十进制值,为浮点数获取浮点数,为 int 获取整数:

>>> Decimal('7')+3
Decimal('10')

【讨论】:

【参考方案5】:

毫不奇怪,Python 有一种方法可以检查某事物是否为数字:

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)

desiredData = `[[1, 4, 7, -50], [0, 0, 0, 12]]`

如果您有任意深度的嵌套列表,则定义一个函数。如果使用 Python 3.x,请将 basestring 替换为 str

这个this 和this 问题可能是相关的。另外,this 和 this。

【讨论】:

【参考方案6】:

我假设您所指的空白是空字符串。由于您要转换所有字符串,无论它们是否包含字符。我们可以简单地检查对象的类型是否为字符串。如果是,我们可以将其转换为整数 0。

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]

【讨论】:

【参考方案7】:
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]]

它适用于不同的数字类型:

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]]

if isinstance(x,numbers.Number) 捕获已经是浮点数、整数等的子元素。如果它不是数字类型,我们首先尝试转换为 int 然后再转换为浮点数,如果这些都不成功,我们只需返回 0

【讨论】:

【参考方案8】:
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)

【讨论】:

【参考方案9】:

考虑到您需要 int 和 float 数据类型,您应该尝试以下代码:

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) 

这可能不是最好的方法,但它仍然可以完成您要求的工作。

【讨论】:

以上是关于在 Python 中将所有非数字转换为 0(零)的主要内容,如果未能解决你的问题,请参考以下文章

在python中将所有零移动到数组的末尾

如何在python中将一维值列表转换为0和1的二维网格[重复]

JavaScript中将字符串类型转换为整形的函数

在python pandas df中将月份数转换为名称

在 Python 中将二进制数组转换为十进制(相当于 R readBin?)

405. 数字转换为十六进制数