Список строк «целые числа» в целые числа, учитывающие «нечисловые» строки Python - PullRequest
1 голос
/ 30 апреля 2019

Я получаю данные из онлайн-базы данных. Возвращает даты и числовые значения в виде строк в списке. т.е. ['87', '79', '50', 'M', '65'] (это значения для графика оси Y, а значения оси X - это годы, связанные с этими значениями, т.е. ['2018', '2017', '2016', '2015', '2014']. Прежде чем я смогу построить эти значения, мне сначала нужно преобразовать их в целые числа. Я достиг этого просто при использовании maxT_int = list(map(int,maxTList) проблема существует, однако, иногда данные отсутствуют и обозначаются как пропущенные буквой «М», как в примере выше.

То, что я хотел бы сделать, это удалить букву «М» или каким-то образом учесть ее и иметь возможность наносить на график значения.

Я могу изобразить значения очень хорошо, когда у меня нет 'M' в списке. Любые предложения о том, как лучше всего решить эту проблему?

Мой полный код указан ниже

import urllib
import datetime
import urllib.request
import ast
from bokeh.plotting import figure
#from bokeh.io import output_file, show, export_png
import numpy as np



# Get user input for day
# in the format of mm-dd
print("Enter a value for the day that you would like to plot.")
print("The format should be mm-dd")
dayofmonth = input("What day would you like to plot? ")


# testing out a range of years
y = datetime.datetime.today().year

# get starting year
ystart = int(input("What year would you like to start with? "))
# get number of years back
ynum = int(input("How many years would you like to plot? "))
# calculate the number of years back to start from current year
diff = y - ystart
#assign values to the list of years
years = list(range(y-diff,y-(diff+ynum), -1))

start = y - diff
endyear = y - (diff+ynum)

i = 0
dateList=[]
minTList=[]
maxTList=[]
for year in years:
    sdate = (str(year) + '-' + dayofmonth)
    #print(sdate)

    url = "http://data.rcc-acis.org/StnData"

    values = {
    "sid": "KGGW",
    "date": sdate,
    "elems": "maxt,mint",
    "meta": "name",
    "output": "json"
    }

    data = urllib.parse.urlencode(values).encode("utf-8")


    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    results = response.read()
    results = results.decode()
    results = ast.literal_eval(results)

    if i < 1:
        n_label = results['meta']['name']
        i = 2
    for x in results["data"]:
            date,maxT,minT = x
            #setting the string of date to datetime

            date = date[0:4]
            date_obj = datetime.datetime.strptime(date,'%Y')
            dateList.append(date_obj)
            minTList.append(minT)
            maxTList.append(maxT)

maxT_int = list(map(int,maxTList))


# setting up the array for numpy
x = np.array(years)
y = np.array(maxT_int)


p = figure(title="Max Temps by Year for the day " + dayofmonth + " " + n_label, x_axis_label='Years',
           y_axis_label='Max Temps', plot_width=1000, plot_height=600)

p.line(x,y,  line_width=2)
output_file("temps.html")
show(p)

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Вы можете использовать numpy.nan и функцию:

import numpy as np

lst = ['87', '79', '50', 'M', '65']

def convert(item):
    if item == 'M':
        return np.nan
    else:
        return int(item)

new_lst = list(map(convert, lst))
print(new_lst)

Или - если вы находитесь в понимании списка:

new_lst = [int(item) if item is not 'M' else np.nan for item in lst]


Оба приведут к
[87, 79, 50, nan, 65]
0 голосов
/ 30 апреля 2019

Вы можете использовать понимание списка, дважды повторяя ваши значения y.

raw_x = ['2018', '2017', '2016', '2015', '2014']
raw_y = ['87', '79', '50', 'M', '65']

clean_x = [x for x, y in zip(raw_x, raw_y) if y != 'M']
clean_y = [y for y in raw_y if y != 'M']
0 голосов
/ 30 апреля 2019

Попробуйте это:

>>> maxTList = ['87', '79', '50', 'M', '65']
>>> maxT_int = [int(item) for item in maxTList if item.isdigit()]
>>> maxT_int
[87, 79, 50, 65]
  • Использует понимание списка (вместо map )
  • Преобразует строку в int , если она содержит только цифры ( [Python 3.Docs]: стр. isdigit () )

Как и сейчас, код просто отбрасывает нечисловые строки (как указано в вопросе), делая maxT_int короче, чем maxTList (в этом случае вам придется применитьтот же алгоритм для другого списка, чтобы убедиться, что вы исключаете соответствующий год).
Если вы хотите, чтобы они были равны, вы можете указать значение по умолчанию, если строка недопустима int (уведомление , если и для порядкаперевернуто):

>>> maxT_int2 = [int(item) if item.isdigit() else -1 for item in maxTList]
[87, 79, 50, -1, 65]
...