Операция со списком, преобразование данных alphanumeri c при пропуске других данных в списке - PullRequest
0 голосов
/ 06 января 2020

спасибо за любую помощь, которую вы можете предоставить. Если есть другой пост / видео / статья, связанная с этим вопросом, я буду рад проверить это.

Язык: Python

Мой вопрос: Как правильно составить приведенный ниже код, чтобы пропустить «N / A» и «De c 25 2019» в списке = число

Я нашел ответ о том, как преобразовать значения alphanumeri c, такие как "1.19T", в числа с плавающей точкой, но я не могу понять, как пропустить даты и "N / A" в список. Любая помощь будет оценена, спасибо.

num = ["11.1", "1.19T", "22.14", "2.09B", "4.57%", "12.92", "N/A", "Dec 25 2019"]
units = {"M": 1_000, "B": 1_000_000, "T": 1_000_000_000, "": 1, "%": .01}
result = []
for n in num:
        try:
            result.append(float(n))
        except ValueError:
            unit = n[-1]
            n = float(n[:-1])
            result.append(n * units[unit])

print(result)

Ответы [ 2 ]

1 голос
/ 06 января 2020

По сути, вы пытаетесь отделить обработку модулей от недопустимых значений, поскольку теперь они обслуживаются одним и тем же оператором try / исключением. Одно (но не единственное) решение заключается в явной обработке единиц:

for n in num: 
    try: 
        if n[-1] in units: 
            n = float(n[:-1]) * units[n[-1]] 
        else: 
            n = float(n) 
    except ValueError: 
        continue 
    result.append(n)

Другой подход, как предлагается в комментариях, заключается в использовании вложенного блока try / исключением. Однако «явное лучше, чем неявное», поэтому я предпочитаю приведенное выше.

0 голосов
/ 06 января 2020

Использование re:

Сначала мне пришлось удалить пустой строковый ключ из вашего units:

units = {"M": 1_000, "B": 1_000_000, "T": 1_000_000_000, "%": .01}

Затем я перебираю все ваши элементы и все сохраненные единицы в измените все литералы на правильные арифметические операции c:

>>> num_formatted=[]
>>> for el in num:
...     x=el
...     for k in units:
...         x=re.sub(r"([0-9\.]+)"+k, r"(\1 * "+str(units[k])+")", x)
...     num_formatted.append(x)
...
>>> print(num_formatted)
['11.1', '(1.19 * 1000000000)', '22.14', '(2.09 * 1000000)', '(4.57 * 0.01)', '12.92', 'N/A', 'Dec 25 2019']

Благодаря такому подходу вы можете иметь более одной единицы на один литерал, и все должно быть вычислено арифметически правильно.

После этого сделано - мы можем просто eval все отформатированные операции:

>>> import numpy as np
>>> num_formatted_final=[]
>>> for el in num_formatted:
...     try:
...         num_formatted_final.append(eval(el))
...     except:
...         num_formatted_final.append(np.nan) #You can put None instead - I suppose np.nan is more logical choice here
...
>>> num_formatted_final
[11.1, 1190000000.0, 22.14, 2089999.9999999998, 0.045700000000000005, 12.92, nan, nan]
...