Compartilhar via


Tutorial: Unir dados de sensor com dados de previsão do clima usando Jupyter Notebook (Python)

A energia eólica é uma fonte de energia alternativa aos combustíveis fósseis para combater a alteração climática. Como o vento não é consistente por natureza, os operadores de energia eólica precisam criar modelos de ML (machine learning) para prever a capacidade de energia eólica. Essa previsão é necessária para atender à demanda de eletricidade e garantir a estabilidade da grade. Neste tutorial, explicaremos como os dados de previsão do tempo dos Azure Mapas são combinados com os dados de demonstração de leituras do clima. Os dados de previsão do tempo são solicitados chamando o serviço Clima dos Azure Mapas.

Neste tutorial, você irá:

  • Crie e execute um Jupyter Notebook no VS Code.
  • Carregar dados de demonstração do arquivo.
  • Chamar as APIs REST dos Azure Mapas no Python.
  • Renderizar dados de localização no mapa.
  • Enriquecer os dados de demonstração com os dados meteorológicos de previsão diária do Azure Mapas.
  • Plotar dados de previsão em gráficos.

Observação

O arquivo do Jupyter Notebook para este projeto pode ser baixado do Repositório de Jupyter Notebooks de Mapas Meteorológicos.

Pré-requisitos

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Observação

Para obter mais informações sobre a autenticação nos Azure Mapas, confira Gerenciar a autenticação nos Azure Mapas.

Instalar pacotes do nível do projeto

O projeto EV Routing and Reachable Range tem dependências das bibliotecas Python aiohttp e IPython. Você pode instalá-los no terminal do Visual Studio usando o pip:

pip install aiohttp
pip install ipython
pip install pandas

Abra um Jupyter Notebook no Visual Studio Code

Baixe e abra o Notebook usado neste tutorial:

  1. Abra o arquivo weatherDataMaps.ipynb no repositório AzureMapsJupyterSamples no GitHub.

  2. Selecione o botão Baixar arquivo bruto no canto superior direito da tela para salvar o arquivo localmente.

    Uma captura de tela mostrando como baixar o arquivo Notebook chamado weatherDataMaps.ipynb do repositório do GitHub.

  3. Abra o Notebook baixado no Visual Studio Code clicando com o botão direito do mouse no arquivo e selecionando Abrir com >Visual Studio Code, ou por meio do Explorador de Arquivos do VS Code.

Carregar as estruturas e os módulos necessários

Depois que o código for adicionado, você pode executar uma célula usando o ícone Executar à esquerda da célula e a saída será exibida abaixo da célula de código.

Execute o script a seguir para carregar todos os módulos e estruturas necessários.

import aiohttp
import pandas as pd
import datetime
from IPython.display import Image, display

Uma captura de tela mostrando como baixar a primeira célula do Notebook contendo as declarações de importação necessárias, com o botão de execução realçado.

Importar dados meteorológicos

Para esse tutorial, usaremos as leituras de dados meteorológicos dos sensores instalados em quatro turbinas eólicas diferentes. Os dados de exemplo consistem em 30 dias de leituras do clima. Essas leituras são coletadas dos data centers meteorológicos próximos a cada localização da turbina. Os dados de demonstração contêm leituras de temperatura e velocidade e direção do vento. Você pode baixar os dados de demonstração contidos em weather_dataset_demo.csv no GitHub. O script abaixo importa dados de demonstração para o Azure Notebook.

df = pd.read_csv("./data/weather_dataset_demo.csv")

Solicitar dados de previsão diária

Em nosso cenário, desejamos solicitar uma previsão diária para cada localização de sensor. O script a seguir chama a API de Previsão Diária do serviço Clima dos Azure Mapas. Essa API retorna a previsão do tempo para cada turbina eólica, para os próximos 15 dias a contar da data atual.

subscription_key = "Your Azure Maps key"

# Get a lists of unique station IDs and their coordinates 
station_ids = pd.unique(df[['StationID']].values.ravel())
coords = pd.unique(df[['latitude','longitude']].values.ravel())

years,months,days = [],[],[]
dates_check=set()
wind_speeds, wind_direction = [], []

# Call azure maps Weather services to get daily forecast data for 15 days from current date
session = aiohttp.ClientSession()
j=-1
for i in range(0, len(coords), 2):
    wind_speeds.append([])
    wind_direction.append([])
    
    query = str(coords[i])+', '+str(coords[i+1])
    forecast_response = await(await session.get("https://atlas.microsoft.com/weather/forecast/daily/json?query={}&api-version=1.0&subscription-key={Your-Azure-Maps-Subscription-key}&duration=15".format(query, subscription_key))).json()
    j+=1
    for day in range(len(forecast_response['forecasts'])):
            date = forecast_response['forecasts'][day]['date'][:10]
            wind_speeds[j].append(forecast_response['forecasts'][day]['day']['wind']['speed']['value'])
            wind_direction[j].append(forecast_response['forecasts'][day]['day']['windGust']['direction']['degrees'])
            
            if date not in dates_check:
                year,month,day= date.split('-')
                years.append(year)
                months.append(month)
                days.append(day)
                dates_check.add(date)
            
await session.close()

O script abaixo renderiza as localizações das turbinas no mapa chamando o serviço Obter Imagem do Mapa.

# Render the turbine locations on the map by calling the Azure Maps Get Map Image service
session = aiohttp.ClientSession()

pins="default|la-25+60|ls12|lc003C62|co9B2F15||'Location A'{} {}|'Location B'{} {}|'Location C'{} {}|'Location D'{} {}".format(coords[1],coords[0],coords[3],coords[2],coords[5],coords[4], coords[7],coords[6])

image_response = "https://atlas.microsoft.com/map/static/png?subscription-key={Your-Azure-Maps-Subscription-key}&api-version=1.0&layer=basic&style=main&zoom=6&center={},{}&pins={}".format(subscription_key,coords[7],coords[6],pins)

static_map_response = await session.get(image_response)

poi_range_map = await static_map_response.content.read()

await session.close()

display(Image(poi_range_map))

Uma captura de tela mostrando as localizações das turbinas em um mapa.

Agrupar os dados de previsão com os dados de demonstração com base na ID da estação. A ID da estação destina-se ao data center meteorológico. Esse agrupamento aumenta os dados de demonstração com os dados de previsão.

# Group forecasted data for all locations
df = df.reset_index(drop=True)
forecast_data = pd.DataFrame(columns=['StationID','latitude','longitude','Year','Month','Day','DryBulbCelsius','WetBulbFarenheit','WetBulbCelsius','DewPointFarenheit','DewPointCelsius','RelativeHumidity','WindSpeed','WindDirection'])

for i in range(len(station_ids)):
    loc_forecast = pd.DataFrame({'StationID':station_ids[i], 'latitude':coords[0], 'longitude':coords[1], 'Year':years, 'Month':months, 'Day':days, 'WindSpeed':wind_speeds[i], 'WindDirection':wind_direction[i]})
    forecast_data = pd.concat([forecast_data,loc_forecast], axis=0, sort=False)
    
combined_weather_data = pd.concat([df,forecast_data])
grouped_weather_data = combined_weather_data.groupby(['StationID'])

A tabela a seguir exibe os dados históricos e de previsão combinados para um dos locais de turbina.

# Display data for first location
grouped_weather_data.get_group(station_ids[0]).reset_index()

Dados agrupados

Plotar dados de previsão

Plotar os valores previstos com relação aos dias para os quais foram previstos. Essa plotagem nos permite ver as alterações de velocidade e direção do vento nos próximos 15 dias.

# Plot wind speed
curr_date = datetime.datetime.now().date()
windsPlot_df = pd.DataFrame({ 'Location A': wind_speeds[0], 'Location B': wind_speeds[1], 'Location C': wind_speeds[2], 'Location D': wind_speeds[3]}, index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind speed")
#Plot wind direction 
windsPlot_df = pd.DataFrame({ 'Location A': wind_direction[0], 'Location B': wind_direction[1], 'Location C': wind_direction[2], 'Location D': wind_direction[3]}, index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind direction")

Os grafos abaixo permitem visualizar os dados de previsão. Para a alteração da velocidade do vento, confira o grafo à esquerda. Para a alteração da direção do vento, confira o gráfico à direita. Esses dados são a previsão para os próximos 15 dias, a partir do dia em que os dados são solicitados.

Uma captura de tela mostrando gráficos de velocidade do vento.

Uma captura de tela mostrando gráficos de direção do vento.

Nesse tutorial, você aprendeu a chamar as APIs REST do Azure Mapas para obter dados de previsão do tempo. Você também aprendeu a visualizar os dados em grafos.

Para explorar as APIs dos Azure Mapas que são usadas neste tutorial, confira:

Para obter uma lista completa das APIs REST dos Azure Mapas, confira APIs REST dos Azure Mapas.

Próximas etapas