Преобразование всех нечисловых значений в 0 (ноль) в Python
Я ищу самый простой способ преобразования всех нечисловых данных (включая пробелы) в 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.
Ответы
Ответ 1
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)
улавливает подэлементы, которые уже являются float, int и т.д., если он не является числовым типом, мы сначала пытаемся выполнить листинг для int, а затем плавать, если ни один из них не является успешным, мы просто возвращаем 0
.
Ответ 2
Другое решение, использующее регулярные выражения
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]]
Примечание Это не работает для чисел в научной нотации
Ответ 3
В качестве альтернативы вы можете использовать модуль 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
заключается в том, что при первом условии вы можете использовать его для получения десятичного значения для цифровой строки и представления float для float и integer для int:
>>> Decimal('7')+3
Decimal('10')
Ответ 4
Целые числа, поплавки и отрицательные числа в кавычках прекрасны:
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]]
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]]
Ответ 5
Учитывая, что вам нужны как типы данных 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)
Это может быть не оптимальный способ сделать это, но все же он выполняет задание, которое вы просили.
Ответ 6
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)
Ответ 7
Неудивительно, что у 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 и .
Ответ 8
Однострочный:
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]]
Ответ 9
Я предполагаю, что пробелы, о которых вы говорите, являются пустыми строками. Поскольку вы хотите преобразовать все строки, независимо от них, содержащие символы или нет. Мы можем просто проверить, является ли тип объекта строкой. Если это так, мы можем преобразовать его в целое число 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]