├── README.md ├── aula-4-visualizacao.Rmd ├── aula-3-pandas.Rmd ├── aula-2-numpy.ipynb └── aula-1-intro.ipynb /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # python4stats 4 | 5 | **Python para Estatística** é um grupo de estudos de Python para análise 6 | de dados. Os estudos irão enfatizar algoritmos, lógica de programação e 7 | estrutura de dados em Python, manipulação e visualização de dados, 8 | estatística descritiva e ajuste de modelos de regressão 9 | 10 | A jornada de estudos aconteceu em 5 módulos de 2 horas cada nos dias 11 | 15, 17, 19, 24 e 26 de Janeiro de 2018, no período das 14h às 16h no 12 | Laboratório de Estatística e Geoinformação (LEG, prédio do Setor de 13 | Ciências Exatas, sala 232). 14 | 15 | O grupo de estudos foi coordenado pelos professores Wagner Bonat, 16 | Walmes Zeviani e Fernando Mayer (LEG/DEST). 17 | 18 | ## Tópicos 19 | 20 | 1. Configuração do ambiente e estruturas de programação 21 | (`aula-1-intro.ipynb`). 22 | 1. Download e instalação do Python e editores. 23 | 2. Módulos, aritmética, lógica, objetos. 24 | 3. Controles de execução e funções. 25 | 2. Álgebra matricial e otimização com `numpy` (`aula-2-numpy.ipynb`). 26 | 1. Operações matriciais. 27 | 2. Distribuições de probabilidade. 28 | 3. Otimização numérica. 29 | 3. Manipulação de dados com `pandas` (`aula-3-pandas.Rmd`). 30 | 1. Leitura de dados no formato texto. 31 | 2. Medidas descritivas. 32 | 3. Manipulação de dados. 33 | 4. Tarefas de split-apply-combine. 34 | 4. Visualização de dados com `matplotlib` (`aula-4-visualizacao.Rmd`). 35 | 1. Gráficos para uma variável. 36 | 2. Gráficos para pares de variáveis. 37 | 5. Modelagem estatística (`aula-5-model.ipynb`). 38 | 1. Modelos de regressão. 39 | 40 | ## Referências 41 | 42 | 1. Grus, J. (2015). *Data science from scratch: first principles with 43 | Python*. Sebastopol, CA: O'Reilly. 44 | 2. Hilpisch, Y. (2014). *Python for finance*. Sebastopol, CA: O'Reilly 45 | Media. 46 | 3. Dale, K. (2016). *Data visualization with Python and JavaScript: 47 | scrape, clean, explore & transform your data*. Sebastopol, CA: 48 | O'Reilly Media. 49 | 4. Menezes, N. N. C. (2014). *Introdução a programação com Python: 50 | algoritmos e lógica de programação para iniciantes*. Novatec, 2014. 51 | -------------------------------------------------------------------------------- /aula-4-visualizacao.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Visualização de Dados com MatPlotLib e Pandas" 3 | subtitle: "Grupo de Estudos de Python para Análise de Dados" 4 | author: "Walmes Zeviani" 5 | output: 6 | html_document: 7 | theme: flatly 8 | toc: true 9 | number_sections: true 10 | --- 11 | 12 | 1. Distribuições de probabilidade e frequência 13 | 1. histograma 14 | 2. densidade 15 | 3. ecdf 16 | 4. boxplot 17 | 5. barras 18 | 2. Relação entre variáveis 19 | 1. dispersão 20 | 2. boxplot 21 | 3. barras 22 | 4. mosaicplot 23 | 5. pares de diagramas 24 | 3. Anotações e geometria 25 | 1. pontos 26 | 2. linhas 27 | 3. poligonos 28 | 4. curvas 29 | 5. eixos 30 | 6. texto 31 | 7. legenda 32 | 33 | ```{python} 34 | import numpy as np 35 | import pandas as pd 36 | print(pd.__version__) 37 | 38 | import matplotlib.pyplot as plt 39 | 40 | # sudo pip3 install seaborn 41 | import seaborn as sb 42 | ``` 43 | 44 | # Gráficos para uma variável 45 | 46 | ## Histogramas 47 | 48 | ```{python} 49 | #----------------------------------------------------------------------- 50 | # Leitura dos dados. 51 | 52 | # Dados de imóveis de 7 bairros em CWB. 53 | u = "http://leg.ufpr.br/~walmes/data/ap_venda7bairros_cwb_210314.txt" 54 | imov = pd.read_table(u) 55 | 56 | # Informações. 57 | imov.info() 58 | 59 | # Extremidades. 60 | imov.head() 61 | imov.tail() 62 | 63 | # Modifica algumas variáveis. 64 | imov.preco = imov.preco/1000 65 | # imov.area = imov.area/1000 66 | 67 | # Descrição de uma delas. 68 | imov.preco.describe() 69 | 70 | # Documentação. 71 | # help(imov.plot.hist) 72 | 73 | #-------------------------------------------- 74 | # Histogramas. 75 | 76 | # Histograma do preço na escala original. 77 | imov['preco'].plot.hist(bins = 30) 78 | plt.show() 79 | 80 | # Histograma do preço na escala log. 81 | np.log(imov['preco']).plot.hist(bins = 30) 82 | plt.show() 83 | 84 | np.log(imov['preco']).plot.hist(bins = 30, 85 | # orientation = 'horizontal', 86 | cumulative = True) 87 | plt.show() 88 | 89 | #-------------------------------------------- 90 | # Densidade suavizada. 91 | 92 | imov.columns 93 | 94 | np.log(imov['preco']).plot.density(color = 'red') 95 | plt.show() 96 | 97 | np.log(imov['area']).plot.density(color = 'magenta') 98 | plt.show() 99 | 100 | imov[['quartos', 'banheiros']].plot.density( 101 | color = ['red', 'green']) 102 | plt.show() 103 | 104 | #----------------------------------------------------------------------- 105 | # Frequência acumulada. 106 | 107 | # Vetor com valores ordenados. 108 | x = imov.area.sort_values() 109 | x = imov.quartos.sort_values() 110 | x.head() 111 | x.tail() 112 | 113 | # Frequências acumuladas. 114 | px = np.linspace(0., 1., len(x)) 115 | 116 | # Vrifica os tamanhos. 117 | len(x) == len(px) 118 | 119 | # Gráfico de distribuição de frequência relativa acumulada. 120 | plt.plot(x, px, drawstyle = 'steps') 121 | plt.show() 122 | 123 | #----------------------------------------------------------------------- 124 | # Gráfico de caixas. 125 | 126 | np.log(imov[['preco']]).plot.box() 127 | plt.show() 128 | 129 | imov[['quartos', 'banheiros', 'vagas']].plot.box() 130 | plt.show() 131 | 132 | #----------------------------------------------------------------------- 133 | # Gráfico de barras. 134 | 135 | imov['ratio'] = imov.preco/imov.area 136 | 137 | imov.columns 138 | 139 | by_bair = imov.groupby('bairro') 140 | 141 | # Tabela resumo com o número de imóveis por bairro. 142 | by_bair.size() 143 | 144 | by_bair.size().plot(kind = 'bar') 145 | plt.show() 146 | 147 | by_bair.size().plot(kind = 'barh') 148 | plt.show() 149 | 150 | by_bair['preco'].median().plot(kind = 'bar') 151 | plt.show() 152 | 153 | by_bair['area'].median().plot(kind = 'barh') 154 | plt.show() 155 | 156 | by_bair['ratio'].mean().plot(kind = 'bar') 157 | plt.show() 158 | 159 | #-------------------------------------------- 160 | # Duas variáveis agrupadoras. 161 | 162 | # Converte bairro para categórica. 163 | imov.bairro = imov.bairro.astype('category') 164 | imov.bairro.values 165 | 166 | keep = imov.bairro.isin(['batel', 'portao']) 167 | imovs = imov[keep] 168 | imovs.info() 169 | 170 | by_bair_vag = imovs.groupby(['bairro', 'vagas']) 171 | 172 | ctb = by_bair_vag.size() 173 | ctb 174 | 175 | ctb.plot(kind = 'barh') 176 | plt.show() 177 | 178 | ctb = by_bair_vag.size().unstack().T 179 | ctb 180 | 181 | ctb.plot(kind = 'barh') 182 | plt.show() 183 | ``` 184 | 185 | ## Gráficos para duas ou mais variáveis 186 | 187 | ```{python} 188 | #----------------------------------------------------------------------- 189 | # Diagrama de dispersão. 190 | 191 | ax = imov.plot.scatter(x = 'area', y = 'preco') 192 | 193 | ax.set_yscale('log') 194 | ax.set_xscale('log') 195 | plt.show() 196 | 197 | #----------------------------------------------------------------------- 198 | 199 | by_bair = imov.groupby(['bairro']) 200 | 201 | by_bair.size() 202 | by_bair[['preco', 'area']].head() 203 | 204 | ax = by_bair.get_group('batel').plot.scatter(x = 'area', 205 | y = 'preco', 206 | color = 'DarkBlue', 207 | label = 'Batel') 208 | ax.set_yscale('log') 209 | ax.set_xscale('log') 210 | ax.xlabel('Log do preço (R$/1000)') 211 | ax.ylabel('Log da área (m^2/1000)') 212 | by_bair.get_group('portao').plot.scatter(x = 'area', 213 | y = 'preco', 214 | color = 'DarkGreen', 215 | label = 'Portão', 216 | ax = ax) 217 | plt.show() 218 | ``` 219 | 220 | # Referências 221 | 222 | 1. Livros 223 | 1. Dale, K. (2016). *Data visualization with Python and JavaScript: 224 | scrape, clean, explore & transform your data*. Sebastopol, CA: 225 | O'Reilly Media. Homepage: 226 | . Source 227 | code: . 228 | 2. Massaron, L. & Mueller, J. (2015). *Python for data science for 229 | dummies*. Hoboken, NJ: John Wiley and Sons, Inc. Homepage: 230 | . 231 | Source code: 232 | 233 | 2. Webpages 234 | 1. . 235 | 2. 236 | 3. . 237 | 4. . 238 | 5. Chris Albon webpage: . 239 | 6. `ggplot` para Python: . 240 | 3. Cheat sheets 241 | 242 | 243 | [`Series`]: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html 244 | [`DataFrame`]: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html 245 | -------------------------------------------------------------------------------- /aula-3-pandas.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Manipulação de Visualização de Dados" 3 | subtitle: "Grupo de Estudos de Python para Análise de Dados" 4 | author: "Walmes Zeviani" 5 | output: 6 | html_document: 7 | theme: flatly 8 | toc: true 9 | number_sections: true 10 | --- 11 | 12 | # Tabela de conteúdo 13 | 14 | 1. Habilitar Python no Emacs 15 | 1. `.emacs` e pacotes. 16 | 2. path para o Anaconda Python 17 | 2. Introdução ao Pandas. 18 | 1. Classes `Series` e `DataFrame`. 19 | 2. Iniciando objetos das classes. 20 | 3. Acesso as propriedades e métodos. 21 | 4. Indexação e seleção. 22 | 5. Modificação de conteúdo. 23 | 6. Modificação de atributos. 24 | 3. Manipulação de dados. 25 | 1. Datasets internos do Python. 26 | 2. Filtros e ordenação. 27 | 3. Criar e excluir registros e variáveis. 28 | 4. Empilhar e fundir tabelas. 29 | 5. Estatística descritiva. 30 | 6. Estatísticas por estrato. 31 | 4. Leitura de arquivos de dados. 32 | 1. Com separador de campo: CSV e TSV. 33 | 2. De campo de comprimento fixo. 34 | 3. Planilhas eletrônicas. 35 | 5. Visualização de dados. 36 | 1. Modelo mental do Python. 37 | 38 | # Python dentro do Emacs 39 | 40 | As instruções a seguir são para habilitação minimalista do Python dentro 41 | do emacs. 42 | 43 | Instale o pacote `elpy` no seu Emacs. De dentro de uma sessão emacs faça 44 | `M-x package-list-packages`. Em seguida, procure pelo `elpy` com `C-s 45 | elpy`. Com o cursor nessa linha, pressione `i` para selecionar o pacote 46 | para instalação e `x` para executar a instalação. Aguarde até o final do 47 | processo. 48 | 49 | Coloque no seu arquivo `.emacs` o seguinte conteúdo. 50 | 51 | ```{lisp, eval = FALSE} 52 | ;;---------------------------------------------------------------------- 53 | ;; Python configuration. 54 | 55 | ;; Install first: M-x package-list-packages C-s elpy. 56 | (elpy-enable) 57 | 58 | ;; Define o interpretador Python. 59 | (custom-set-variables 60 | ;; '(python-shell-interpreter "~/anaconda/bin/python3") 61 | '(python-shell-interpreter "/usr/bin/python3") 62 | ) 63 | 64 | ;; Habilita autocomplete após os pontos. 65 | (setq jedi:complete-on-dot t) 66 | 67 | ;; Python3 console, C-c C-p para abrir o console 68 | (defcustom python-shell-interpreter "python3" 69 | "Default Python interpreter for shell." 70 | :type 'string 71 | :group 'python) 72 | 73 | ;;---------------------------------------------------------------------- 74 | ``` 75 | 76 | A partir de agora, quando abrir arquivos `.py`, o modo Python 77 | (`python-mode`) estará operando. Faça `C-RET` para avaliar uma linha ou 78 | região selecionada. Na primeira execução o console Python será aberto em 79 | um buffer paralelo. 80 | 81 | # Configuração para usar Python com Rmarkdown 82 | 83 | Indicar o caminho para o interpretador Python no primeiro chunk. 84 | 85 | ```{r setup, include = TRUE} 86 | # Usa o Python 3.x para processar os chunks. 87 | knitr::opts_chunk$set( 88 | engine.path = "/usr/bin/python3") 89 | ``` 90 | 91 | Verificar se a versão vista ao processar o documento é de fato a versão 92 | pretendida. 93 | 94 | ```{python} 95 | # Exibe a versão da engine Python sendo usada. 96 | import sys 97 | print(sys.version) 98 | ``` 99 | 100 | No caso de ausência de pacotes, executar em terminal shell as instruções 101 | abaixo para instalação dos pacotes. 102 | 103 | ``` 104 | # Instala pacotes no Python 3.x. 105 | sudo apt-get install python3-pip 106 | sudo pip3 install numpy scipy pandas matplotlib scikit-learn 107 | sudo apt-get install python3-tk 108 | 109 | # Para instalar o Jupyter e o Spyder. 110 | sudo pip3 install jupyter 111 | sudo pip3 install spyder 112 | ``` 113 | 114 | Varificar se os gráficos estão sendo inseridos dentro do documento. 115 | 116 | ```{python} 117 | # Importa bibliotecas gráficas. 118 | import matplotlib as mpl 119 | import matplotlib.pyplot as plt 120 | 121 | # Cria um gráfico simples. 122 | plt.plot([1,2,3,4]) 123 | plt.show() 124 | ``` 125 | 126 | Segundo discussão no [issues/812] do repositório do rmarkdown, é 127 | possível usar o Python fornecido pelo Anaconda. 128 | 129 | IMPORTANTE: estar com a última versão do pacote `rmarkdown`. Instalar a 130 | versão disponível no github. É necessário instalar o pacote 131 | `reticulate` que é chamado quando a engine é Python. 132 | 133 | ```{r, eval = FALSE} 134 | devtools::install_github("rstudio/rmarkdown") 135 | install.packages("reticulate") 136 | ``` 137 | 138 | # Introdução ao Pandas 139 | 140 | O tipo "primitivo" de objeto fornecido pelo Pandas é o [`Series`]. Nada 141 | mais é que o nome para um vetor de dados. Ele é contruido a partir do 142 | `numpy.array()`. 143 | 144 | ```{python} 145 | # Importa o módulo. 146 | import pandas as pd 147 | 148 | # Exibe a documentação. 149 | # help(pd.Series) 150 | 151 | # Criando um objeto tipo Series. 152 | s = pd.Series(range(10)) 153 | print(s) 154 | 155 | # Atributos da classe (não termina com parênteses.) 156 | print(s.dtype) 157 | print(s.nbytes) 158 | print(s.shape) 159 | print(s.values) 160 | 161 | type(s) 162 | 163 | # (funções) Métodos associadas a classe. 164 | # ATTENTION: mostrar recursos de REGEX do Emacs para colocar o print(). 165 | s.min() 166 | s.max() 167 | s.mean() 168 | s.median() 169 | s.std() 170 | s.head(3) 171 | s.tail(3) 172 | s.describe() 173 | ``` 174 | 175 | O [`DataFrame`] é o tipo de objeto que representa a tabela de dados. Ele é 176 | contruído a partir do `Series`. 177 | 178 | ```{python} 179 | # Dicionário com listas de mesmo tamanho. 180 | d = {'grr': [1, 2, 3, 4], 181 | 'nome': ["Andre", "Gabriela", "Rodrigo", "Tatiana"], 182 | 'nota': [9.0, 9.2, 7.9, 8.3]} 183 | d 184 | 185 | # Conversão para DataFrame. 186 | df = pd.DataFrame(data = d) 187 | df 188 | 189 | # Atributos. 190 | df.shape # Comprimento em cada dimensão. 191 | df.size # Número de entradas. 192 | df.axes # Nome dos eixos. 193 | df.values # Representação NumPy. 194 | df.dtypes # Tipagem de cada coluna. 195 | 196 | # Acesso as `Series`. Pelo nome não pode haver espaços. 197 | df.grr 198 | df.nome 199 | df.nota 200 | 201 | # Pelo nome dos índices. Permite mais de uma coluna. 202 | df[['nota']] 203 | df[['nota', 'nome']] 204 | 205 | # Por sequência de posições. 206 | df.iloc[:,1:3] 207 | 208 | # Seleção de linhas (três formas equivalentes). 209 | df.iloc[1:3] 210 | df.iloc[1:3,] 211 | df.iloc[1:3,:] 212 | 213 | # Seleção de linhas e colunas. 214 | df.iloc[1:3, 0:2] 215 | # df.iloc[1:3, ['nome', 'grr']] 216 | df.iloc[1:3, ][['nome', 'grr']] 217 | 218 | # Retonar o nome das colunas. 219 | df.columns 220 | df.columns[-2] # É uma lista. 221 | df.columns[[0, 2]] # É uma lista. 222 | 223 | # Usar as opções combinadas (passando a lista). 224 | df.iloc[1:3, ][df.columns[-2]] 225 | 226 | df[[0, 2]] 227 | df.iloc[:, [0, 2]] 228 | df.iloc[[0, 2], [0, 2]] 229 | df.iloc[[0, 2]] 230 | df.iloc[[0, 2],] 231 | df.iloc[[0, 2],:] 232 | 233 | x = range(0, 3, 2) 234 | df.iloc[x,:] 235 | df.iloc[0:3:2,:] 236 | 237 | # Com intervalo dado pelo nome dos extremos. 238 | df.loc[:, 'grr':'nota'] 239 | 240 | # Dar nome para as linhas. 241 | df = df.set_index('grr') 242 | df 243 | 244 | # `grr` deixou de ser uma coluna para der o ID. 245 | df.columns 246 | 247 | # Restaura o índice e retorna `grr` como coluna. 248 | df.reset_index(inplace = True) 249 | df.columns 250 | 251 | # Usa nome como índice dos registros. 252 | df = df.set_index('nome') 253 | df.columns 254 | df 255 | 256 | # Seleciona linhas pelo nome do índice. 257 | df.loc["Andre"] 258 | df.loc["Tatiana"] 259 | 260 | # Pela posição. 261 | df.iloc[0] 262 | df.iloc[-1] 263 | 264 | # Mudar o nome das colunas. 265 | df.columns = ['Grr', 'Nota'] 266 | df 267 | 268 | df.rename(columns = {'Grr': 'GRR', 269 | 'Nota': 'nota'}, 270 | inplace = True) 271 | df 272 | 273 | # Estrutura do DataFrame. 274 | df.info() 275 | 276 | # Medidas descritivas para variáveis numéricas. 277 | df.describe() 278 | 279 | # Restaura o índice. 280 | df.reset_index(inplace = True) 281 | df 282 | 283 | # Adiciona um registro ao final da tabela (usa dict). 284 | df = pd.DataFrame(data = d) 285 | df 286 | df = df.append({'grr': 5, 'nota': 10, 'nome': 'Pedro', 'falta': 6}, 287 | ignore_index = True) 288 | df 289 | 290 | df = df.append(pd.DataFrame({'grr': [6, 7], 'nota': [10, 9], 'nome': 291 | ['Maicon', 'Maria'], 'falta': [6, 0]}), 292 | ignore_index = True) 293 | df 294 | 295 | # Exclui o registro pelo índice. 296 | df.drop([3], inplace = True) 297 | df 298 | 299 | dg = pd.DataFrame([[99, 'Carolina', 9.5, 8], 300 | [98, 'Lígia', 7.1, 10]], 301 | columns = ['grr', 'nome', 'nota', 'falta']) 302 | dg 303 | 304 | # Empilha duas tabelas. 305 | df.append(dg) 306 | df.append(dg, ignore_index = True) 307 | df 308 | dg 309 | 310 | # Remove uma colunas. 311 | df.drop(['falta'], axis = 1) 312 | df 313 | 314 | # Criando uma coluna. 315 | df.falta = pd.Series([10, 0, 4, 2, 18, 16], 316 | index = df.index) 317 | df 318 | ``` 319 | 320 | # Manipulação de dados 321 | 322 | ```{r, eval = FALSE} 323 | u <- "http://leg.ufpr.br/~walmes/data/triathlon.txt" 324 | download.file(u, destfile = basename(u)) 325 | getwd() 326 | dir() 327 | ``` 328 | 329 | ## Importação de TSV 330 | 331 | ```{python} 332 | # Lendo um TSV. 333 | cap = pd.read_table('http://leg.ufpr.br/~walmes/data/desfolha.txt') 334 | 335 | # Informações. 336 | cap.info() 337 | 338 | # Exibe a tabela. 339 | cap 340 | 341 | # Medidas descritivas para as variáveis numéricas. 342 | cap.describe() 343 | 344 | # Descrição pelo tipo de variável. 345 | cap.describe(include = 'int') 346 | cap.describe(include = 'float') 347 | cap.describe(include = ['int', 'float']) 348 | cap.describe(include = 'object') 349 | cap.describe(include = 'all') 350 | ``` 351 | 352 | ## Medidas descritivas por estrato 353 | 354 | ```{python} 355 | # Média por estrato. 356 | cap.groupby(['estag'])['pcapu'].mean() 357 | cap.groupby(['estag'])['pcapu', 'ncapu'].mean() 358 | cap.groupby(['estag', 'desf'])['pcapu', 'ncapu'].mean() 359 | cap.groupby(['estag', 'desf'])['pcapu', 'ncapu'].describe() 360 | 361 | capg = cap.groupby(['estag', 'desf']) 362 | capg 363 | 364 | # Médias de duas variáveis. 365 | m = cap.groupby(['estag'])['pcapu', 'ncapu'].mean() 366 | m 367 | m.reset_index(inplace = True) 368 | m 369 | 370 | # Máximo de uma outra variável, 371 | M = cap.groupby(['estag'])['alt'].max() 372 | M 373 | M = pd.DataFrame(M) 374 | M.reset_index(inplace = True) 375 | M 376 | 377 | pd.merge(m, M, on = ['estag']) 378 | ``` 379 | 380 | ## Função com medidas descritivas 381 | 382 | ```{python} 383 | import numpy as np 384 | 385 | cap.groupby(['estag'])['pcapu'].agg({ 386 | "media" : np.mean, 387 | "errpd" : np.std, 388 | "ampli" : lambda x: np.max(x) - np.min(x), 389 | "cv" : lambda x: 100 * np.std(x)/np.mean(x) 390 | }) 391 | 392 | res = cap.groupby(['estag', 'desf'])['pcapu', 'alt'].agg({ 393 | "media" : np.mean, 394 | "errpd" : np.std 395 | }) 396 | res 397 | 398 | # Organização do objeto. 399 | res.info() 400 | 401 | # Atributos de linhas e colunas são MultiIndex. 402 | res.columns 403 | res.columns.levels 404 | res.index 405 | res.index.levels 406 | 407 | res.reset_index() 408 | ``` 409 | 410 | ## Filtros 411 | 412 | ```{python} 413 | #-------------------------------------------- 414 | # Máscaras lógicas. 415 | 416 | cap[cap.alt > 150] 417 | cap[cap['alt'] > 150] 418 | 419 | # IMPORTANT: tem que ter os parenteses. 420 | cap[(cap.alt > 150) & ((cap.ncapu >= 10) | (cap.nnos > 30))] 421 | 422 | #-------------------------------------------- 423 | # Partições feitas com o groupby(). 424 | 425 | # Com uma variável de agrupamento. 426 | gb = cap.groupby(['estag']) 427 | gb 428 | gb.groups 429 | 430 | gb.get_group('1veg') 431 | gb.get_group('5capu') 432 | 433 | pd.concat([gb.get_group('1veg'), 434 | gb.get_group('5capu')]) 435 | 436 | # Com duas variáveis de agrupamento. 437 | gb = cap.groupby(['estag', 'desf']) 438 | gb 439 | 440 | gb.groups 441 | 442 | # Tem que usar uma tupla. 443 | gb.get_group(('1veg', 0)) 444 | gb.get_group(('5capu', 100)) 445 | 446 | pd.concat([gb.get_group(('1veg', 0)), 447 | gb.get_group(('5capu', 100))]) 448 | ``` 449 | 450 | ## Ordenação 451 | 452 | ```{python} 453 | cap.sort_values(['alt'], ascending = False).head(10) 454 | cap.sort_values(['ncapu', 'alt']).head(10) 455 | ``` 456 | 457 | ## Junção de tabelas 458 | 459 | ```{python} 460 | tabA = pd.DataFrame({ 461 | 'nome': ["Marcos", "Julia", "Gabriel"], 462 | 'nota': [8.9, 6.7, 8.1] 463 | }) 464 | 465 | tabB = pd.DataFrame({ 466 | 'nome': ["Ulisses", "Andrea", "Ana", "Pedro"], 467 | 'nota': [7.7, 7.1, 8.3, 5.0] 468 | }) 469 | 470 | tabC = pd.DataFrame({ 471 | 'falta': [10, 12, 4, 0], 472 | 'idade': [18, 20, 18, 19] 473 | }) 474 | tabC.index = [0, 1, 3, 4] # Index com falha. 475 | 476 | #-------------------------------------------- 477 | # Empilhar. 478 | 479 | # Usando append(). 480 | tabA.append(tabB) 481 | tabA.append(tabB, ignore_index = True) 482 | 483 | # Usando concat(). 484 | pd.concat([tabA, tabB], axis = 0) 485 | pd.concat([tabA, tabB], axis = 0, ignore_index = True) 486 | 487 | #-------------------------------------------- 488 | # Lado a lado. 489 | 490 | pd.concat([tabB, tabC], axis = 1) 491 | 492 | #-------------------------------------------- 493 | # De formato long para wide e vice versa. 494 | 495 | tab_wide = pd.DataFrame({ 496 | 'trat' : ["A", "B", "C"], 497 | 'aval1' : [1, 2, 3], 498 | 'aval2' : [10, 20, 30], 499 | 'aval3' : [100, 200, 300] 500 | }) 501 | tab_wide 502 | 503 | tab_long = pd.melt(tab_wide, 504 | id_vars = ['trat'], 505 | var_name = 'x', 506 | value_name = 'y') 507 | tab_long 508 | 509 | # Para complicar, vamos remover uma linha. 510 | tab_long.drop([3], axis = 0, inplace = True) 511 | 512 | tab_wide = tab_long.pivot(index = 'trat', 513 | columns = 'x', 514 | values = 'y') 515 | tab_wide.reset_index(inplace = True) 516 | tab_wide 517 | ``` 518 | 519 | # Acesso a documentação interna em PDF 520 | 521 | ```{sh, eval = FALSE} 522 | pydoc3 -p 1234 # Abre o navegador na home da documentação. 523 | ``` 524 | 525 | # Referências 526 | 527 | 1. Livros 528 | 1. Dale, K. (2016). *Data visualization with Python and JavaScript: 529 | scrape, clean, explore & transform your data*. Sebastopol, CA: 530 | O'Reilly Media. Homepage: 531 | . Source 532 | code: . 533 | 2. Massaron, L. & Mueller, J. (2015). *Python for data science for 534 | dummies*. Hoboken, NJ: John Wiley and Sons, Inc. Homepage: 535 | . 536 | Source code: 537 | 538 | 2. Webpages 539 | 1. Chris Albon webpage: . 540 | 2. . 541 | 3. . 542 | 3. Cheat sheets 543 | 2. 544 | 3. 545 | 4. 546 | 5. 547 | 548 | 549 | [`Series`]: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html 550 | [`DataFrame`]: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html 551 | [issues/812]: https://github.com/rstudio/rmarkdown/issues/812 552 | -------------------------------------------------------------------------------- /aula-2-numpy.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Encontro II\n", 8 | "\n", 9 | "## Objetivo\n", 10 | "\n", 11 | "Neste segundo encontro vamos discutir os seguintes assuntos: \n", 12 | "\n", 13 | " - Estruturas numpy;\n", 14 | " - Álgebra linear usando numpy e modulos associados;\n", 15 | " - Distribuições de probabilidade;\n", 16 | " - Otimização;\n", 17 | " - Integração e derivação numéricas;\n", 18 | " - Exemplos.\n", 19 | "\n", 20 | "A biblioteca `numpy` é o centro de toda computação científica em python. Ela implementa objetos `array` multidimensionais de alta performance e métodos para manipular tais objetos. \n", 21 | "\n", 22 | "## Estruturas numpy\n", 23 | "\n", 24 | "Um `numpy array` é um gride de valores todos de mesmo tipo indexado por um `tuple` de inteiros não negativos. O número de dimensões é o `size` do `array` e o `shape` do `array` é uma `tuple` que mostra o tamanho de cada dimensão. Podemos inicializar arrays usando objetos do tipo `list` e acessar elementos do array usando colchetes (*square brackets*).\n" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "name": "stdout", 34 | "output_type": "stream", 35 | "text": [ 36 | "\n", 37 | "3\n", 38 | "(3,)\n", 39 | "[10 2 3]\n", 40 | "[[1 2 3]\n", 41 | " [4 5 6]]\n", 42 | "6\n", 43 | "(2, 3)\n" 44 | ] 45 | } 46 | ], 47 | "source": [ 48 | "import numpy as np\n", 49 | "a = np.array([1, 2, 3]) # Cria um array de rank = 1\n", 50 | "print(type(a))\n", 51 | "print(a.size) # Tamanho\n", 52 | "print(a.shape) # Dimensão\n", 53 | "\n", 54 | "a[0] = 10 # Modifica um elemento do array\n", 55 | "print(a)\n", 56 | "\n", 57 | "b = np.array([[1,2,3],[4,5,6]]) # array 2 linhas e 3 colunas\n", 58 | "print(b)\n", 59 | "print(b.size)\n", 60 | "print(b.shape)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "`Numpy` também fornece várias opções para inicializar arrays." 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 16, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "[[ 0. 0. 0.]\n", 80 | " [ 0. 0. 0.]\n", 81 | " [ 0. 0. 0.]]\n", 82 | "[[ 1. 1. 1.]\n", 83 | " [ 1. 1. 1.]]\n", 84 | "[[10 10 10 10]\n", 85 | " [10 10 10 10]\n", 86 | " [10 10 10 10]\n", 87 | " [10 10 10 10]]\n", 88 | "[[ 1. 0. 0.]\n", 89 | " [ 0. 1. 0.]\n", 90 | " [ 0. 0. 1.]]\n", 91 | "[[ 0.23672878 0.58462308]\n", 92 | " [ 0.19209855 0.02922875]]\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "a = np.zeros((3,3)) # array de zeros 2x2\n", 98 | "print(a)\n", 99 | "\n", 100 | "b = np.ones((2,3)) # array de 1's 2x3\n", 101 | "print(b)\n", 102 | "\n", 103 | "c = np.full((4,4), 10) # array 4x4 com todas as entradas iguais a 10\n", 104 | "print(c)\n", 105 | "\n", 106 | "d = np.eye(3) # Matrix identidade 3x3\n", 107 | "print(d)\n", 108 | "\n", 109 | "e = np.random.random((2,2)) # Matrix 3x3 de números aleatórios\n", 110 | "print(e)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "### Acessando elementos do array\n", 118 | "\n", 119 | "Similar a objetos do tipo `list` um `array` pode ser fatiados (*sliced*). Como os arrays são multidimensionais podemos especificar uma fatia para cada dimensão do `array`." 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 71, 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "(3, 4)\n", 132 | "[1 2 3 4]\n", 133 | "[[1 2 3 4]\n", 134 | " [5 6 7 8]]\n", 135 | "[ 9 10 11 12]\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # array \n", 141 | "print(a.shape) # 3x4\n", 142 | "print(a[0,]) # Primeira linha\n", 143 | "print(a[0:2,]) # Primeira e segunda linha\n", 144 | "print(a[2,]) # Terceira linha" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "Acessando as colunas do `array`." 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 72, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "name": "stdout", 161 | "output_type": "stream", 162 | "text": [ 163 | "[[ 3 4]\n", 164 | " [ 7 8]\n", 165 | " [11 12]]\n", 166 | "[ 4 8 12]\n", 167 | "[[ 3]\n", 168 | " [ 7]\n", 169 | " [11]]\n" 170 | ] 171 | } 172 | ], 173 | "source": [ 174 | "print(a[:,2:4]) # Terceira e quarta coluna\n", 175 | "print(a[:,3]) # Apenas a quarta coluna rsrs\n", 176 | "print(a[:,2:3]) # Isso é estranho!!" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "Acessando elementos específicos." 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 85, 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "[7 8]\n", 196 | "[[100 3]\n", 197 | " [ 6 7]]\n", 198 | "[[ 1 100 3 4]\n", 199 | " [ 5 6 7 8]\n", 200 | " [ 9 10 11 12]]\n", 201 | "[[50 3]\n", 202 | " [ 6 7]]\n", 203 | "[[ 1 100 3 4]\n", 204 | " [ 5 6 7 8]\n", 205 | " [ 9 10 11 12]]\n" 206 | ] 207 | } 208 | ], 209 | "source": [ 210 | "a[1,1] # Segunda linha segunda coluna\n", 211 | "print(a[1,2:4]) # Segunda linha colunas 3 e 4.\n", 212 | "\n", 213 | "# Tirando apenas uma fatia do array e criando um novo\n", 214 | "b = a[:2, 1:3]\n", 215 | "print(b) \n", 216 | "# Mais cuidado os objetos ainda são os mesmos\n", 217 | "b[0,0] = 100\n", 218 | "print(a) \n", 219 | "\n", 220 | "# Evitando esse comportamento usando função deepcopy do module copy\n", 221 | "from copy import deepcopy\n", 222 | "c = deepcopy(a[:2, 1:3])\n", 223 | "c[0,0] = 50\n", 224 | "print(c)\n", 225 | "print(a)" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": {}, 231 | "source": [ 232 | "Capturar pedaços de um `array` que não sejam fatias é um pouco mais complicado. \n", 233 | "Suponha que queremos capturar a primeira e terceira linhas." 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 94, 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "[[ 1 2 3 4]\n", 246 | " [ 5 6 7 8]\n", 247 | " [ 9 10 11 12]]\n", 248 | "[[100 2 3 4]\n", 249 | " [ 9 10 11 12]]\n", 250 | "(2, 4)\n" 251 | ] 252 | } 253 | ], 254 | "source": [ 255 | "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n", 256 | "b = np.array([a[0,],a[2,]]) # novo array\n", 257 | "b[0,0] = 100\n", 258 | "print(a) # note que agora realmente temos um novo array que não altera o array anterior\n", 259 | "print(b)\n", 260 | "print(b.shape) #2x4" 261 | ] 262 | }, 263 | { 264 | "cell_type": "markdown", 265 | "metadata": {}, 266 | "source": [ 267 | "Importante entender o que acontece com objetos `array`. Quando capturamos um `slice` do `array` a fatia capturada ainda é parte do `array` original e portanto qualquer modificação na fatia vai mudar também o `array`. Entretanto, quando capturamos fatias ou pedaços de um `array` e com essas fatias ou pedaços criamos um novo `array` que portanto não é mais parte do `array` original. Assim, mudanças no novo `array` não afetaram o `array` original." 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "Podemos selecionar elementos de um `array` usando variáveis boleanas. " 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 96, 280 | "metadata": {}, 281 | "outputs": [ 282 | { 283 | "data": { 284 | "text/plain": [ 285 | "array([ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])" 286 | ] 287 | }, 288 | "execution_count": 96, 289 | "metadata": {}, 290 | "output_type": "execute_result" 291 | } 292 | ], 293 | "source": [ 294 | "a[a > 2]" 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "Existem muitas opções de como manipular e capturar fatias e/ou pedaços de `array` usando `numpy` para mais detalhes ver (http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html)." 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "## Álgebra linear usando `numpy`\n", 309 | "\n", 310 | "A classe `ndarray` disponibilizada pela biblioteca `numpy` é muito geral e flexível. Entretanto, em estatística em geral estamos interessados em matrizes. Uma matriz nada mais é do que um `array` bidimensional. Devido a sua importância não apenas em estatística mais em diversas áreas a biblioteca `numpy` oferece ferramentas específicas para trabalhar com matrizes em python. Para inicializar uma matriz em python o processo é muito similar a inicialização de um `array`. O interessante é que agora operações matemáticas simples podem ser feitas em todos os elementos da matriz que pode ser apenas um vetor linha ou coluna como mostra o código abaixo." 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 9, 316 | "metadata": {}, 317 | "outputs": [ 318 | { 319 | "name": "stdout", 320 | "output_type": "stream", 321 | "text": [ 322 | "[[2 4 6]]\n", 323 | "[[2]\n", 324 | " [4]\n", 325 | " [6]]\n", 326 | "[[ 1. 1.41421356 1.73205081]]\n", 327 | "[[ 2.71828183 7.3890561 20.08553692]]\n", 328 | "[[ 0. 0.69314718 1.09861229]]\n", 329 | "[[2 4 6]]\n", 330 | "[[0]\n", 331 | " [0]\n", 332 | " [0]]\n", 333 | "[[ 1. 1. 1.]]\n", 334 | "[[1 4 9]]\n" 335 | ] 336 | } 337 | ], 338 | "source": [ 339 | "a = np.matrix([[1,2,3]]) # vetor linha\n", 340 | "a.shape\n", 341 | "b = a.T # transposto (vetor coluna)\n", 342 | "\n", 343 | "print(a * 2) # Multiplicação por constante\n", 344 | "print(b * 2)\n", 345 | "\n", 346 | "print(np.sqrt(a)) # Raiz de cada elemento de a\n", 347 | "print(np.exp(a)) # Exponencial de cada elemento de a\n", 348 | "print(np.log(a)) # Logaritmo de cada elemento de a\n", 349 | "\n", 350 | "print(a + a) # Soma dois vetores (elementwise)\n", 351 | "print(b - b) # Subtrai dois vetores\n", 352 | "print(a/a) # Divisão elementwise\n", 353 | "print(np.multiply(a,a)) # multiplicação elementwise" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "Para inicializar uma matriz usando a `numpy` usamos uma sintaxe parecida com a inicialização de uma `list`." 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": 3, 366 | "metadata": {}, 367 | "outputs": [ 368 | { 369 | "name": "stdout", 370 | "output_type": "stream", 371 | "text": [ 372 | "(3, 3)\n", 373 | "(3, 3)\n" 374 | ] 375 | } 376 | ], 377 | "source": [ 378 | "A = np.matrix([ [1, 0.8, 0.6], [0.8, 1, 0.4], [0.6, 0.4, 1]])\n", 379 | "B = np.matrix([ [1, 0.2, 0.3], [0.2, 1, 0.5], [0.3, 0.5, 1]])\n", 380 | "print(A.shape)\n", 381 | "print(B.shape)" 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "metadata": {}, 387 | "source": [ 388 | "Operações matriciais são executadas de forma intuitiva." 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 7, 394 | "metadata": {}, 395 | "outputs": [ 396 | { 397 | "name": "stdout", 398 | "output_type": "stream", 399 | "text": [ 400 | "[[ 2. 1. 0.9]\n", 401 | " [ 1. 2. 0.9]\n", 402 | " [ 0.9 0.9 2. ]]\n", 403 | "[[ 0. 0.6 0.3]\n", 404 | " [ 0.6 0. -0.1]\n", 405 | " [ 0.3 -0.1 0. ]]\n", 406 | "[[ 1.34 1.3 1.3 ]\n", 407 | " [ 1.12 1.36 1.14]\n", 408 | " [ 0.98 1.02 1.38]]\n", 409 | "[ 1. 1. 1.]\n", 410 | "[[ 2.71828183 2.22554093 1.8221188 ]\n", 411 | " [ 2.22554093 2.71828183 1.4918247 ]\n", 412 | " [ 1.8221188 1.4918247 2.71828183]]\n" 413 | ] 414 | } 415 | ], 416 | "source": [ 417 | "print(A + B) # Soma Elementwise\n", 418 | "print(A - B) # Subtração\n", 419 | "print(np.dot(A,B)) # Multiplicação matricial\n", 420 | "print(np.diag(A)) # Pega só a diagonal\n", 421 | "print(np.exp(A)) # Exponencial de cada entrada - util para geoestatística ;)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "As principais operações de álgebra linear estão implementadas em um modulo extra da `numpy` chamado de `numpy.linalg`. Sendo, vamos importar a biblioteca `numpy.linalg` usando apenas o prefixo `lp` e fazer algumas operações matriciais básicas como inversão, cálculo de determinantes e decomposições de autovalor e autovetor e Cholesky. Também podemos obter algumas propriedades da matrix como sua norma e rank." 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 9, 434 | "metadata": {}, 435 | "outputs": [ 436 | { 437 | "name": "stdout", 438 | "output_type": "stream", 439 | "text": [ 440 | "[[ 3.75 -2.5 -1.25 ]\n", 441 | " [-2.5 2.85714286 0.35714286]\n", 442 | " [-1.25 0.35714286 1.60714286]]\n", 443 | "0.224\n", 444 | "(array([ 2.21493472, 0.16242348, 0.6226418 ]), matrix([[ 0.63457746, 0.75716113, -0.15497893],\n", 445 | " [ 0.58437383, -0.60130182, -0.54492509],\n", 446 | " [ 0.50578521, -0.25523155, 0.82403773]]))\n", 447 | "[[ 1. 0. 0. ]\n", 448 | " [ 0.8 0.6 0. ]\n", 449 | " [ 0.6 -0.13333333 0.78881064]]\n", 450 | "2.30651251893\n", 451 | "3\n" 452 | ] 453 | } 454 | ], 455 | "source": [ 456 | "import numpy.linalg as lp\n", 457 | "\n", 458 | "print(lp.inv(A)) # inverse de A\n", 459 | "print(lp.det(A)) # determinante de A\n", 460 | "\n", 461 | "print(lp.eig(A)) # Autovalores e autovetores\n", 462 | "print(lp.cholesky(A)) # Decomposição de Cholesky\n", 463 | "\n", 464 | "print(lp.norm(A)) # Norma\n", 465 | "print(lp.matrix_rank(A)) # Rank (numero de colunas li)" 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": {}, 471 | "source": [ 472 | "Outra ferramenta muito útil é a solução de sistemas lineares do tipo $Ax = b$. Em python isso é facilmente implementado, novamente usando o modulo `numpy.linalg`." 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 11, 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "data": { 482 | "text/plain": [ 483 | "matrix([[-5. ],\n", 484 | " [ 4.28571429],\n", 485 | " [ 4.28571429]])" 486 | ] 487 | }, 488 | "execution_count": 11, 489 | "metadata": {}, 490 | "output_type": "execute_result" 491 | } 492 | ], 493 | "source": [ 494 | "A = np.matrix([ [1, 0.8, 0.6], [0.8, 1, 0.4], [0.6, 0.4, 1]])\n", 495 | "b = np.matrix([[1,2,3]]).T # Note o transposto precisamos de um vetor coluna\n", 496 | "lp.solve(A,b)" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "## Distribuições de probabilidade\n", 504 | "\n", 505 | "As principais distribuições de probabilidade estão implementadas na biblioteca `scipy.stats`. Todas as distribuições implementadas nesta biblioteca tem um conjunto rico de métodos os principais são:\n", 506 | "\n", 507 | " - pdf: função densidade probabilidade ou função de probabilidade.\n", 508 | " - cdf: função de distribuição acumulada.\n", 509 | " - sf: função de sobreviência (complementar da cdf).\n", 510 | " - ppf: função quantil (inversa da cdf).\n", 511 | " - isf: inversa da função de sobreviência (complementar do inverso da cdf).\n", 512 | " - stats: esperança, variância, assimetria (skew) e curtose.\n", 513 | " - moment: Momentos não centrais.\n", 514 | " - rvs: amostras aleatórias.\n", 515 | "\n", 516 | "Interessante notar que funções como a pdf e cdf são definidas na reta real, mesmo que a distribuição não corresponda a este suporte. Neste caso as funções vão retornar zero no caso da pdf e 0 ou 1 no caso da cdf. Por exemplo, o suporta da distribuição beta é o intervalo aberto (0,1). Assim, se a pdf fora deste intervalo será 0 e a cdf abaixo de 0 será 0 e acima de 1 será 1. \n", 517 | "\n", 518 | "Outro aspecto interessante da forma como a biblioteca `scipy.stats` implementa as distribuições é que você pode usá-las de duas formas: a primeira é a chamada forma congelada onde você inicializa a distribuição com os parâmetros de interesse e depois usa. A segunda você aplica a função diretamente passando como argumentos o ponto e os parâmetros para a avaliação da função. Vamos ver um exemplo," 519 | ] 520 | }, 521 | { 522 | "cell_type": "code", 523 | "execution_count": 20, 524 | "metadata": {}, 525 | "outputs": [ 526 | { 527 | "name": "stdout", 528 | "output_type": "stream", 529 | "text": [ 530 | "0.0880163316911\n", 531 | "0.0880163316911\n" 532 | ] 533 | } 534 | ], 535 | "source": [ 536 | "import scipy.stats as sp\n", 537 | "\n", 538 | "print(sp.norm.pdf(5, 3, 4)) # Avalia a distribuição Normal com mu = 3 e sigma2 = 4 no ponto 5.\n", 539 | "\n", 540 | "mydist = sp.norm(3, 4) # Modo frozen \n", 541 | "print(mydist.pdf(5))" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "metadata": {}, 547 | "source": [ 548 | "A biblioteca `scipy.stats` é muito rica em distribuições e a documentação é muito detalhada recomendo que veja o site da biblioteca [scipy.stats](https://docs.scipy.org/doc/scipy/reference/stats.html). Um outro aspecto útil é que todas as distribuições contínuas estão implementadas como um modelo de locação e escala. Esta é uma abordagem um pouco não usual, mas uma grande vantagem é que sabemos a parametrização de todas as distribuições contínuas previamente. A lista de distribuições é muito extensa e inclui distribuições multivariadas como a Gaussiana, Dirichlet e Wishart. \n", 549 | "\n", 550 | "Como um exemplo para explorar como usamos as distribuições da `scipy.stats` vou usar em um primeiro momento a distribuição Gaussiana porque suas propriedades são bem conhecidas. Em um segundo momento fazer usar uma distribuição não usual como a *generalized extreme value distribution*. Vamos calcular algumas quantidades da distribuição Gaussiana." 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 59, 556 | "metadata": {}, 557 | "outputs": [ 558 | { 559 | "name": "stdout", 560 | "output_type": "stream", 561 | "text": [ 562 | "10.0 25.0 0.0 0.0\n" 563 | ] 564 | } 565 | ], 566 | "source": [ 567 | "my_norm = sp.norm(loc = 10, scale = 5)\n", 568 | "# Aspectos da distribuição\n", 569 | "my_norm.expect() # Esperança\n", 570 | "my_norm.median() # Mediana\n", 571 | "my_norm.moment(n = 1) # Primeiro momento (esperança)\n", 572 | "my_norm.moment(n = 2) # Segundo momento\n", 573 | "my_norm.stats() # Média e variancia\n", 574 | "my_norm.std() # Erro padrão\n", 575 | "my_norm.var() # Variance\n", 576 | "my_norm.entropy() # Entropia\n", 577 | "\n", 578 | "mean, var, skew, kurt = my_norm.stats(moments = 'mvsk')\n", 579 | "print(mean, var, skew, kurt)" 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": {}, 585 | "source": [ 586 | "Ainda não falamos sobre gráficos em python, mas eu vou inicializar uma figura, mais detalhes serão vistos nos próximos encontros. \n", 587 | "Gráfico da função densidade probabilidade." 588 | ] 589 | }, 590 | { 591 | "cell_type": "code", 592 | "execution_count": 77, 593 | "metadata": {}, 594 | "outputs": [ 595 | { 596 | "data": { 597 | "text/plain": [ 598 | "[]" 599 | ] 600 | }, 601 | "execution_count": 77, 602 | "metadata": {}, 603 | "output_type": "execute_result" 604 | } 605 | ], 606 | "source": [ 607 | "import matplotlib.pyplot as plt\n", 608 | "fig, ax = plt.subplots(1, 1)\n", 609 | "\n", 610 | "x = np.linspace(my_norm.ppf(0.01), my_norm.ppf(0.99), 100)\n", 611 | "ax.plot(x, my_norm.pdf(x), 'r-', lw=1, alpha=0.6, label='norm pdf')" 612 | ] 613 | }, 614 | { 615 | "cell_type": "markdown", 616 | "metadata": {}, 617 | "source": [ 618 | "Vamos simular uma amostra aleatório da distribuição Gaussiana e fazer um histograma e sobrepor a densidade que acabamos de calcular." 619 | ] 620 | }, 621 | { 622 | "cell_type": "code", 623 | "execution_count": 78, 624 | "metadata": {}, 625 | "outputs": [ 626 | { 627 | "data": { 628 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD8CAYAAACb4nSYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt0VeWd//H3NwnkSgKGi8gtKHgBuYcgiIDiBewAbZUq\n7TjMjB17GefX1jX91fa36nRcnV/HaaeOXfrraGuVsa3KaK1MS+uliCKXkABRLhGJgBKhEm6B3G/f\n3x97Q9PjCdlJTvLsc873tVYW++zznHM+OZx8s/PsZz+PqCrGGGOSQ4rrAMYYY/qOFX1jjEkiVvSN\nMSaJWNE3xpgkYkXfGGOSiBV9Y4xJIlb0jTEmiVjRN8aYJGJF3xhjkkia6wCRBg8erAUFBa5jGGNM\nXNm2bdsxVR3SWbvQFf2CggJKS0tdxzDGmLgiIu8HaWfdO8YYk0Ss6BtjTBKxom+MMUnEir4xxiSR\nQEVfRBaJyF4RqRCRe6Pcny4iz/r3F4tIgb+/n4isEpGdIlIuIt+MbXxjjDFd0WnRF5FU4BFgMTAB\nWCEiEyKa3QmcVNVxwIPAA/7+5UC6qk4CZgBfOPsLwRhjTN8LcqRfBFSo6n5VbQKeAZZFtFkGrPK3\nnwMWiogACmSLSBqQCTQBp2OS3BhjTJcFKfojgEPtblf6+6K2UdUWoBrIx/sFUAscAT4AfqCqJ3qY\n2RhjTDcFuThLouyLXFi3ozZFQCtwETAI2CAir6rq/j97sMhdwF0Ao0ePDhDJGIcOH4Zdu2D/fjh5\n0tuXlQVjx8Kll8Jll4FE+5EwpnM5OTnU1NQA8PWvf521a9dy88038/3vfz8mzx+k6FcCo9rdHgkc\n7qBNpd+VkwecAD4L/F5Vm4GjIrIRKAT+rOir6mPAYwCFhYW2UrsJp3fegd/9Do4cgenTYcYMyM/3\nCvyZM3DgAKxeDa2tcMMNMGcOpNgAuUTT0tJCWlrfTGbw6KOPUlVVRXp6esyeM0jyEmC8iIwFPgRu\nxyvm7a0BVgKbgVuBdaqqIvIBcJ2I/BzIAq4C/iNW4Y3pE7W1XjHftw+WLfOKfbQf+smTYelSr92L\nL8LGjfBXfwXDh/d9ZtOhgwcPsnjxYubOncumTZsYMWIEL774IpmZmZSVlfHFL36Ruro6LrnkEn72\ns58xaNAgFixYwJw5c9i4cSNLly5l586dZGZm8s477/D+++/zxBNPsGrVKjZv3sysWbN48sknP/a6\nBQUF3Hbbbbz22msA/PKXv2TcuHEcOHCAz372s7S0tLBo0aJz7ZcuXUptbS2zZs3im9/8Jrfddlts\n3gBV7fQLuBl4F3gP+D/+vvuBpf52BvDfQAWwFbjY35/j798N7AG+3tlrzZgxQ40JjUOHVO+9V/Xp\np1UbGoI/rq1Ndf161XvuUS0p6b18pssOHDigqampumPHDlVVXb58uT711FOqqjpp0iRdv369qqp+\n+9vf1q985Suqqjp//nz90pe+dO45Vq5cqbfddpu2tbXpr3/9ax0wYIC+/fbb2traqtOnTz/33O2N\nGTNGv/vd76qq6qpVq/QTn/iEqqouWbJEV61apaqqDz/8sGZnZ597TPvtzgClGqCeB/obRVXXAmsj\n9t3XbrsBb3hm5ONqou03Ji7s2gVPPAG33w4zZ3btsSIwfz5ccgk8/DBUVcGiRdbXH80XvhD753z0\n0fPePXbsWKZOnQrAjBkzOHjwINXV1Zw6dYr58+cDsHLlSpYv/1P5ijzSXrJkCSLCpEmTGDZsGJMm\nTQJg4sSJHDx48Nzzt7dixYpz/37ta18DYOPGjTz//PMA3HHHHXzjG9/oznccWOhm2TQmFHbvhief\nhC9/2Svc3TVyJNx7L/zoR15f/1/8RcwiJoxOCnRvaN9HnpqaSn19faePyc7OjvocKSkpf/Z8KSkp\ntLS0RH0OafdLv6Pt3mZnmYyJtG+fd4Tf04J/1sCB8NWvwtat8OqrPX8+0yvy8vIYNGgQGzZsAOCp\np546d9QfK88+++y5f2fPng3A1VdfzTPPPAPAL37xi5i+XjR2pG9Mex995B15fv7zcPHFsXve3Fz4\n2tfg+9+HQYO8k8EmdFatWnXuRO7FF1/ME088EdPnb2xsZNasWbS1tfH0008D8NBDD/HZz36Whx56\niFtuuSWmrxeNeP3/4VFYWKi2iIpxoqEBvvc9b7jl3Lm98xqHDsFDD8E998BFF/XOa5hQOrtA1ODB\ng3vl+UVkm6oWdtbOuneMAVD1+vDHj++9gg8wahQsXw4//jHU1fXe6xjTASv6xgC88QacOOGN1Olt\ns2bBhAng/3lvksPBgwd77Si/K6zoG3P0qHcx1d/+bfSLrnrDLbfA+++DdWWaPmYnck1ya2vzRuos\nWQIXXthp852V1TF76X6LbyX/Jz/haOYQ2vIGnrftpJF5MXtdk9zsSN8kt9de847uFyzo85duHjWG\n2qLZDPyfF/r8tU3ysqJvktepU7B2LfzlXzq7UvbMdTfS78iHpL+zx8nrm+RjRd8kr9WrYd48GDbM\nXYZ+/Ti17FYGvvg80tTkLodJGlb0TXIqL/dOpN58s+skNF56OU2jRpPz+h9cRzFJwE7kmrjT45Op\nbW0MffznnF54Iw0fhWOs/OnFSxj6ox9QWzS705O6xvSEHembpJO1bSttGRk0XDnFdZRzWgddQG3R\nbHJfXtt5Y2N6wIq+SSrS2EjuK7+j+ualoZvm+My1N5Cxt5x+hytdRzEJzIq+SSrZm96gseBimkcX\nuI7yMZqRwZmFN5L7+9+4jmISmBV9kzSkvo6cDes5c8Ni11E6VDtzNmlHj9L/4AHXUUyCClT0RWSR\niOwVkQoRuTfK/eki8qx/f7GIFPj7PyciZe2+2kTk48vJGNMHct58nYbLJ9AyZKjrKB1LS/OO9l/+\nreskJkF1WvRFJBV4BFgMTABWiMiEiGZ3AidVdRzwIPAAgKr+QlWnqupU4A7goKqWxfIbMCYIqasl\nZ9MGzly/qPPGjtVNn0nqqVP0f2+f6ygmAQU50i8CKlR1v6o2Ac8AyyLaLANW+dvPAQvl4+t/rQBs\nWkHjRM6G9dRPmkLrBfmuo3QuNZXT199E7iu/d53EJKAgRX8EcKjd7Up/X9Q2qtoCVAORP123YUXf\nOCD19eRs2ciZBde7jhJY/dQZpFafov+B/a6jmAQTpOhHG9cWudzWeduIyCygTlV3RX0BkbtEpFRE\nSquqqgJEMia47C0babjsivg4yj8rJYUz869jwPpXXCcxCSZI0a8ERrW7PRI43FEbEUkD8oAT7e6/\nnfMc5avqY6paqKqFQ4YMCZLbmECkqYmcja/H1VH+WXUziuh35LCN2zcxFaTolwDjRWSsiPTHK+Br\nItqsAVb627cC69RffFdEUoDleOcCjOlTWaVbaBo1hpYLh7uO0nX9+lEzdwE5621OHhM7nRZ9v4/+\nbuAloBxYraq7ReR+EVnqN3scyBeRCuAeoP2wznlApapa56TpW21t5Gx4nZr5C10n6bbaotlk7NsL\nx465jmISRKAJ11R1LbA2Yt997bYb8I7moz12PXBV9yMa0z0Ze3bSlpND05gC11G6TTMyqJ05i8Hr\n1sFnPuM6jkkAdkWuSVg5G9Zz5pprQzfHTlfVzJkPmzdDXThmBDXxzYq+SUj93j9IanU1DVdOdh2l\nx9oGDoQrr4Q333QdxSQAK/omIeVsfJ2aufMhJUE+4jfcAOvWeQu5G9MDCfITYcyfpFSfIuPdd6gr\nnOU6SuyMHg0XXABlNouJ6Rkr+ibhZG/ZSN3UGWhGhusosXXddfDaa65TmDhnRd8klpYWsku2UDvn\nGtdJYm/aNDh6FCrtYi3TfVb0TULJ3FlG84XDaRk6zHWU2EtNhXnzYP1610lMHLOibxJKzqYNiXmU\nf9Y118C2bTZ803SbFX2TMPodriTldDUNl090HaX35ObCxIlQXOw6iYlTVvRNwsgu3kTdrDmJM0yz\nI/Pmweuvg0ZOdmtM5xL8p8MkC2loIPOtHdQm0jDNjowf7xX8igrXSUwcsqJvEkJm2TYax11KW26e\n6yi9T8Q72n/jDddJTByyom/inyo5WzZSO2uO6yR9Z/Zs2LkTzpxxncTEGSv6Ju71q/wAaWykcdyl\nrqP0nawsmDLFTuiaLrOib+JedskWaouuivvZNLts7lxvEjY7oWu6wIq+iWvS2Ejm22XUTZ/pOkrf\nGzfOm4Btv61PZIKzom/iWubbO2gcewlteQNdR+l7In862jcmoEBFX0QWicheEakQkXuj3J8uIs/6\n9xeLSEG7+yaLyGYR2S0iO0UkwWbBMi5llWyhriiJF2abPRt27ID6etdJTJzotOiLSCrwCLAYmACs\nEJEJEc3uBE6q6jjgQeAB/7FpwM+BL6rqRGAB0Byz9CappX30R9JOnqDhssiPYxIZMAAuvxxKS10n\nMXEiyJF+EVChqvtVtQl4BlgW0WYZsMrffg5YKCIC3Ai8rapvAajqcVVtjU10k+yythVTN70w8a/A\n7czVV8OmTa5TmDgR5KdlBHCo3e1Kf1/UNqraAlQD+cClgIrISyKyXUT+d88jGwO0tpK1vZS6wiTu\n2jlr4kQ4fhyOHHGdxMSBIEU/2ji4yDFiHbVJA+YCn/P//ZSILPzYC4jcJSKlIlJaVVUVIJJJdhnv\nltOSP5iWIUNdR3EvJQWuusqO9k0gQYp+JTCq3e2RwOGO2vj9+HnACX//66p6TFXrgLXA9MgXUNXH\nVLVQVQuHDBnS9e/CJJ2s0q3UzShyHSM8rr4atmyxNXRNp4IU/RJgvIiMFZH+wO3Amog2a4CV/vat\nwDpVVeAlYLKIZPm/DOYDe2IT3SSrlJozpL/3LvWTp7mOEh7DhsHgwbBrl+skJuQ6Lfp+H/3deAW8\nHFitqrtF5H4RWeo3exzIF5EK4B7gXv+xJ4Ef4v3iKAO2q+pvY/9tmGSS+dZ2Gi6fmHhr4PbU7Nmw\nebPrFCbk0oI0UtW1eF0z7ffd1267AVjewWN/jjds05iYyNpWwunFS1zHCJ/CQvjVr6C2FrKzXacx\nIZXkY91M3Dl8mJTaGhovGe86SfhkZXkjeWzMvjkPK/omvmzeTP00G5vfIeviMZ2wnxwTP9raoLjY\nRu2cz4QJ3pj9P/7RdRITUlb0TfwoL4dBg2xs/vmkpMCsWd7wTWOisKJv4sfmzV73hTm/q67yFlex\nefZNFFb0TXxoaPDGoBcWuk4SfiNHQmYm7NvnOokJISv6Jj5s3w6XXgo5Oa6TxIerrrIuHhOVFX0T\nH4qLvUJmgikq8ubZb7aZzM2fs6Jvwu/kSTh0CCZPdp0kfgwcCGPGQFmZ6yQmZKzom/DbuhWmT4e0\nQBeQm7POntA1ph0r+ibcVL2+6VmzXCeJP9OmeSdzz5xxncSEiBV9E24ffgiNjTBunOsk8Sc93esS\ns2kZTDtW9E24FRd7R/kSbZ0e0ynr4jERrOib8Gpr8/rzi2zahW674gpvWoajR10nMSFhRd+E1969\nkJsLw4e7ThK/UlJg5kw72jfnWNE34bV1q53AjYWiIu+9tGkZDAEXUTGmzzU3e2PMP/lJ10lCYWdl\ndfcfnDqQoWcaObn5bZpHF3T54ZNG5nX/tU3oBDrSF5FFIrJXRCpE5N4o96eLyLP+/cUiUuDvLxCR\nehEp87/+M7bxTcJ66y3v4qI8Kzg9JkL91Blk7djmOokJgU6LvoikAo8Ai4EJwAoRmRDR7E7gpKqO\nAx4EHmh333uqOtX/+mKMcptEZ107MVU3rZDMt3dAa6vrKMaxIEf6RUCFqu5X1SbgGWBZRJtlwCp/\n+zlgoYiNsTPdVFsL777rXVxkYqI1fzAt+YNJ37fXdRTjWJCiPwI41O52pb8vahtVbQGqgXz/vrEi\nskNEXheRa3qY1ySDbdu8tV4zMlwnSSj1U6eTVWYXaiW7IEU/2hF75DCAjtocAUar6jTgHuCXIpL7\nsRcQuUtESkWktKqqKkAkk9CKi21sfi+onzyNjHf2II2NrqMYh4IU/UpgVLvbI4HDHbURkTQgDzih\nqo2qehxAVbcB7wGXRr6Aqj6mqoWqWjhkyJCufxcmcRw/DkeOeEf6JqbacgbQNGYsGXt2uo5iHApS\n9EuA8SIyVkT6A7cDayLarAFW+tu3AutUVUVkiH8iGBG5GBgP7I9NdJOQtm6FGTNsRs1eUjd1Blll\nNoonmXVa9P0++ruBl4ByYLWq7haR+0Vkqd/scSBfRCrwunHODuucB7wtIm/hneD9oqqeiPU3YRKE\nqk270MsaJkyi//sHSKmxmTeTVaDDKVVdC6yN2Hdfu+0GYHmUxz0PPN/DjCZZfPihtxauzajZazQ9\nnYbLJ5D59g5q58xzHcc4YNMwmPA4ewLXRvv2qrqphWSWbXcdwzhiRd+EgyqUlNgFWX2gcfxlpB0/\nRurxY66jGAes6Jtw2LcPsrPhootcJ0l8qanUT5pqJ3STlBV9Ew42Nr9P1U0rJHNHqc28mYSs6Bv3\nWlpgxw4r+n2oefQYpLWNfh8e6ryxSShW9I17O3fCiBEwaJDrJMlDhLqp0+2EbhKyom/cs7H5TtRP\nKyTrre3espQmaVjRN27V1cGePd5VuKZPtQwdRmtuHunv7XMdxfQhK/rGrR07vMW7s7JcJ0lK507o\nmqRhRd+4tWWLjc13qH7KNDL37EKamlxHMX3Eir5x5+RJb+qFK690nSRptQ3IpWnUaDLKd7uOYvqI\nFX3jztat3upY/fq5TpLUrIsnuVjRN+4UF1vXTgg0TJhE+oEKm3kzSVjRN25UVkJ9PYwf7zpJ0tOM\nDBoun0jmzjLXUUwfsKJv3Dh7lG8zaoZC3bRCsrZbF08ysKJv+l5bm9efb107odF46eWknjxB6jFb\nozrR2Zp0ptt2VlZ363Hp+/aSq/2pas2Cbj6HibGUFOqnTCdrRylnbljsOo3pRYGO9EVkkYjsFZEK\nEbk3yv3pIvKsf3+xiBRE3D9aRGpE5B9jE9vEs8wdpdRNn+k6holQN22G18VjM28mtE6Lvr+w+SPA\nYmACsEJEJkQ0uxM4qarjgAeBByLufxD4Xc/jmngnjY1k7tlF/ZRprqOYCM0jRqH90uj//kHXUUwv\nCnKkXwRUqOp+VW0CngGWRbRZBqzyt58DFop4Z+hE5JPAfsCu/jBk7NlJ05gC2gbkuo5iIol4J3R3\nlLhOYnpRkKI/Amg/6Xalvy9qG1VtAaqBfBHJBr4B/HPPo5pEkLWjlLpp1rUTVvVTC8l8u8xb48Ak\npCBFP9qYushOv47a/DPwoKrWnPcFRO4SkVIRKa2qstEDiSql+hT9P3if+omTXEcxHWgdNIimi0aQ\nUb7LdRTTS4IU/UpgVLvbI4HDHbURkTQgDzgBzAL+TUQOAl8FviUid0e+gKo+pqqFqlo4ZMiQLn8T\nJj5klW2n/srJNu1CyNXbmP2EFqTolwDjRWSsiPQHbgfWRLRZA6z0t28F1qnnGlUtUNUC4D+A/6uq\nD8cou4knqmTtKLFRO3Gg/sopNi1DAuu06Pt99HcDLwHlwGpV3S0i94vIUr/Z43h9+BXAPcDHhnWa\n5NbvyIdIQyNNYy9xHcV04ty0DG/ZUoqJKNDFWaq6Flgbse++dtsNwPJOnuM73chnEkTWthLqZsy0\naRfiRN2MInJ/9z/UXj3fdRQTYzYNg+l9LS1klm2zrp040njJeFJqa0g7Enn6zsQ7K/qm12W8W07L\nkKG05g92HcUElZLin9C1MfuJxoq+6XVe106R6ximi+pmFJG1o9SbIM8kDCv6plel1NaQ/t671E+a\n6jqK6aKWIUNpuSAfdtvF9InEir7pVZk7ttFw+UQ0I8N1FNMNddNnwqZNrmOYGLKib3qPKtmlxdQV\n2rz58ap+ynQoL4ea815Ub+KIFX3Ta/odrkQaGmi8xJZEjFeamQmTJ3srnZmEYEXf9Jqs0q3UFRbZ\n2Px4N2eOdfEkECv6pne0tJBVts1G7SSCyy7zFrH/4APXSUwMWNE3vSJz906aLhpB66ALXEcxPSXi\nHe1v3Og6iYkBK/qmV2SVbKZu5mzXMUyszJkDJSXQ3Ow6iekhK/om5lJPHKff4Q9t3vxEcsEFUFAA\n220StnhnRd/EXFbJFuqnzrB58xPN3Lnw5puuU5gesqJvYqutjextW6mdaWPzE87kyXDkCBw96jqJ\n6QEr+iam0veW05qbR8vwyGWUTdxLS4OrrrKj/ThnRd/EVPbWzdTOmuM6hukt11wDmzfbwulxzIq+\niZmUU6dIP/Ae9ZOnuY5iesuwYXDhhfDWW66TmG4KVPRFZJGI7BWRChH52FKIIpIuIs/69xeLSIG/\nv0hEyvyvt0TkU7GNb8Iku3QLdVOmo+nprqOY3jRvHmzY4DqF6aZOi76IpAKPAIuBCcAKEZkQ0exO\n4KSqjgMeBB7w9+8CClV1KrAIeFREAi3RaOJMWxtZJVuom2Vj8xPetGlQWQlVVa6TmG4IcqRfBFSo\n6n5VbQKeAZZFtFkGrPK3nwMWioioap2/sDpABqCxCG3CJ31vOW0Dcmm+aKTrKKa3nT2ha0f7cSlI\n0R8BHGp3u9LfF7WNX+SrgXwAEZklIruBncAX2/0SMAkkZ8ub1F51tesYpq/Mm+dNwmZX6MadIEU/\n2hSJkUfsHbZR1WJVnQjMBL4pIh9bTUNE7hKRUhEprbI/GeNO6onj9Dv0AXVTpruOYvrK0KEwapRd\noRuHghT9SmBUu9sjgcMdtfH77POAE+0bqGo5UAtcGfkCqvqYqhaqauGQIUOCpzehkF280Vthya7A\nTS7z58Prr7tOYbooSNEvAcaLyFgR6Q/cDqyJaLMGWOlv3wqsU1X1H5MGICJjgMuAgzFJbsKhuZms\n0q3WtZOMJk+GEyfg0KHO25rQ6LTo+33wdwMvAeXAalXdLSL3i8hSv9njQL6IVAD3AGeHdc4F3hKR\nMuAF4MuqeizW34RxJ3NnGc3DL6J1sP2FlnRSUry+fTvajyuBhk+q6lpgbcS++9ptNwDLozzuKeCp\nHmY0YaVKzsY3OHP9Ta6TGFfmzoV/+if41KcgO9t1GhOAXZFruq3fB++TUldHw2WRl22YpJGb63Xz\n2AIrccOKvum2nM1vUDPnGu/PfJO8rr0W1q+HtjbXSUwA9tNquqe6mox3yr2Fz01yKyiAvDzYudN1\nEhOAFX3TPW+8Qf2UaWhmluskJgyuvRbWrXOdwgRgRd90XXMzvP46NVfPd53EhMX06fDHP3pz8phQ\ns6Jvuq64GAoKaBk6zHUSExZpaXDddfDqq66TmE5Y0Tddo+r9YF9/veskJmyuucabZ7+62nUScx5W\n9E3X7NkDqalw2WWuk5iwycqCoiJvJI8JLSv6pmteecU7ypdoc+yZpLdwIbzxBjQ2uk5iOmBF3wT3\nwQfeybqZM10nMWE1dChceqldrBViVvRNcC+/7B3lp9niZ+Y8brrJO+/T2uo6iYnCir4J5tgxrz9/\n7lzXSUzYFRRAfj6UlrpOYqKwom+CeeUVb0bFjI+tgWPMx910k/eXodoKqWFjRd907vRp2LrVG4dt\nTBATJ3on+21qhtCxzlnTuVde8RbCzs11ncQ4sLOye+PuM2Zcw4Cnf0XVoNHdGu01aWRet17XnJ8d\n6Zvzq6mBN9+EG290ncTEmYYrpyCNDaRXvOs6imnHir45vz/8AWbMgEGDXCcx8UaEM9fewIA/vOw6\niWknUNEXkUUisldEKkTk3ij3p4vIs/79xSJS4O+/QUS2ichO/1/rFI4ntbXeUniLFrlOYuJU/ZTp\npJ6upv/+CtdRjK/Toi8iqcAjwGJgArBCRCKXSroTOKmq44AHgQf8/ceAJao6CW/hdFs6MZ68+ipM\nmwaDB7tOYuJVSgqnr7+J3Jd/ZyN5QiLIkX4RUKGq+1W1CXgGWBbRZhmwyt9+DlgoIqKqO1T1sL9/\nN5AhIumxCG56WU2Nd5R/882uk5g4Vz91Bqlnqkl/b5/rKIZgRX8EcKjd7Up/X9Q2qtoCVAP5EW1u\nAXaoqk3KEQ9eftnry8+P/G80potSUjh9/SIGvGJH+2EQpOhHG2sV+T933jYiMhGvy+cLUV9A5C4R\nKRWR0qqqqgCRTK+qrvZG7Cxe7DqJSRD1U6aTUl9H+t5y11GSXpCiXwmMand7JHC4ozYikgbkASf8\n2yOBF4C/UtX3or2Aqj6mqoWqWjhkyJCufQcm9tauhdmz4YILXCcxiSIlhdM33kze739jR/uOBSn6\nJcB4ERkrIv2B24E1EW3W4J2oBbgVWKeqKiIDgd8C31RVm3YvHlRVQUmJHeWbmGuYOBnt14/Msu2u\noyS1Tou+30d/N/ASUA6sVtXdInK/iCz1mz0O5ItIBXAPcHZY593AOODbIlLmfw2N+XdhYufFF705\n0XNyXCcxiUaE6sVLyH15LbS0uE6TtAJNw6Cqa4G1Efvua7fdACyP8rjvAt/tYUbTV95/H959F+64\nw3USk6CaLh5Hy9ChZG/ZSO3c+a7jJCW7Itd4VOG//xuWLoV0G1Vrek/14qUMeO0VpK7WdZSkZEXf\neMrKoK4O5sxxncQkuJYLh9Nw5WRybXoGJ6zoG69/9fnnYflySLGPhOl9p29YTNb2EtKqjrqOknTs\nJ9x40y0MHw5XXOE6iUkSbTkDOLPgevJ+84IN4exjVvST3cmT3tW3n/mM6yQmydRcPY/U48fIKN/l\nOkpSsaKf7J57DhYsALsozvS1tDSql95C3v/8GpqbXadJGrZyVpzr7qpGAOn79jLwrXc4es8n0R48\njzHd1Xjp5TRfNIIB61/lzA12QWBfsCP9JCVNTQz81WpOLbsF7d/fdRyTxE4t+TQ5mzaQ9tEfXUdJ\nClb0k9SAP7xE06jRNF4x0XUUk+TaBg7k9A2LGPjCajup2wes6CehtCMfklWyheoln3IdxRgAaq+a\ni7S2klW8yXWUhGdFP9m0tjJo9S85vXgJbQNyXacxxpOSwslbbif35bWknjzhOk1Cs6KfZAa89gpt\nubnUFc5yHcWYP9Ny4XBqrlnAwOeetm6eXmRFP4n0O1xJ9uY3Ofnp20CirXtjjFs18xeS0thI9hab\nib23WNGbHgQEAAAI4klEQVRPEtLUxKCn/4vqv/gkbXkDXccxJrqUFE5+5nPe0op/tNE8vcGKfpLI\n++2vaR4xivppha6jGHNeLUOHcfrGm+GnP7V593uBFf0kkLH7bdLf3cupZbe6jmJMIHWz5njLdb7w\ngusoCceKfoJLPXGcgb9azYnb70AzM13HMSYYEVi5Enbs8Kb9NjETqOiLyCIR2SsiFSJyb5T700Xk\nWf/+YhEp8Pfni8hrIlIjIg/HNrrpVHMzFzz1M84svJHmMQWu0xjTNdnZ8Hd/Bz//ubd2s4mJTou+\niKQCjwCLgQnAChGZENHsTuCkqo4DHgQe8Pc3AN8G/jFmiU0wqgx88TlahgyldvY1rtMY0z1jx8In\nPgH/+Z/Q2Og6TUIIcqRfBFSo6n5VbQKeAZZFtFkGrPK3nwMWioioaq2qvolX/E0fyt74Bv0rD3Hq\nlttteKaJbwsWwOjR8OSTNn4/BoIU/RHAoXa3K/19UduoagtQDeTHIqDpuvR332HA+lc5vvLzqK13\na+KdCHzuc3DqFPz2t67TxL0gRT/aYWLkr9sgbTp+AZG7RKRUREqrrO+uR9KOfMigZ3/Oic/9Na2D\nLnAdx5jYSEuDL30JNm2CLVtcp4lrQYp+JTCq3e2RwOGO2ohIGpAHBJ5AQ1UfU9VCVS0cYot5dFvK\nqVPkP/kTqpfeQtPYS1zHMSa2cnPhH/7BW/invNx1mrgVpOiXAONFZKyI9AduB9ZEtFkDrPS3bwXW\nqVrnW19Kqa1h8M9+TO2cedRPmeY6jjG9Y/hw+MIX4PHH4eBB12niUqdF3++jvxt4CSgHVqvqbhG5\nX0SW+s0eB/JFpAK4Bzg3rFNEDgI/BP5aRCqjjPwxPST1deT/9Mc0TJhEzfzrXMcxpneNHw933AGP\nPAIffug6TdwJtFyiqq4F1kbsu6/ddgOwvIPHFvQgn+mE1NeT/8RjNI29hNM3fcJ1HGP6xpQp0NQE\nP/oRfPWr3l8AJhC7Ijee1dUx+PEf03zRSG9BFBuaaZLJzJnw6U/Dgw9CZaXrNHHDin68On0afvhD\nGgsupnrZLVbwTXKaNQtuuw0eeggOHHCdJi4E6t4xIfPRR96ftXPmcHry1VbwTULaWVkdrOGwcaTf\n+CkG/esPOXnrih6v+zxpZF6PHh92dqQfb/btgx/8ABYv9i5Pt4JvDI1XTOT4ys8z6PlnyN68wXWc\nULOiH0/efBMefRT+5m9g7lzXaYwJlebRBVR96Stkb36TgS+shtZW15FCyYp+PGhuhqeegpdfhq9/\nHSbYqFdjomnNH0zVl79GSnU1gx97mJRTp1xHCh0r+mF37Bh873ve8LRvfQuGDXOdyJhQ04wMTqz8\nPA1XXMnQh/+d9H17XUcKFTuRG3bp6XD99TB7tvXfGxOUCDULFtI0ZiyaYse27VnRD7sBA2DOHNcp\njIlLTWMvdh0hdOxXoDHGJBEr+sYYk0Ss6BtjTBKxPv0YCXz1oDHGOGRH+sYYk0Ss6BtjTBKxom+M\nMUnEir4xxiSRQCdyRWQR8BCQCvxUVf814v504L+AGcBx4DZVPejf903gTqAV+F+q+lLM0htjTIy5\nHJTRF9M6d3qkLyKpwCPAYmACsCLKOrd3AidVdRzwIPCA/9gJeAupTwQWAf/Pfz5jjDEOBDnSLwIq\nVHU/gIg8AywD9rRrswz4jr/9HPCwiIi//xlVbQQO+AunFwGbYxP/42zopDHGdCxIn/4I4FC725X+\nvqhtVLUFqAbyAz7WGGNMHwlypB9takcN2CbIYxGRu4C7/Js1IhLWuVAHA8dch+iieMscb3nBMveF\neMsLfZ95TJBGQYp+JTCq3e2RwOEO2lSKSBqQB5wI+FhU9THgsSCBXRKRUlUtdJ2jK+Itc7zlBcvc\nF+ItL4Q3c5DunRJgvIiMFZH+eCdm10S0WQOs9LdvBdapqvr7bxeRdBEZC4wHtsYmujHGmK7q9Ehf\nVVtE5G7gJbwhmz9T1d0icj9QqqprgMeBp/wTtSfwfjHgt1uNd9K3Bfh7VbWFK40xxpFA4/RVdS2w\nNmLffe22G4DlHTz2X4B/6UHGMAl9F1QU8ZY53vKCZe4L8ZYXQppZvF4YY4wxycCmYTDGmCRiRb+L\nROQ7IvKhiJT5Xze7zhSNiCwSkb0iUiEi97rOE4SIHBSRnf77Wuo6TzQi8jMROSoiu9rtu0BEXhGR\nff6/g1xmjNRB5tB+jkVklIi8JiLlIrJbRL7i7w/l+3yevKF8j617p4tE5DtAjar+wHWWjvhTXbwL\n3IA3bLYEWKGqe877QMdE5CBQqKqhHY8tIvOAGuC/VPVKf9+/ASdU9V/9X7CDVPUbLnO210Hm7xDS\nz7GIDAeGq+p2ERkAbAM+Cfw1IXyfz5P3M4TwPbYj/cR0buoMVW0Czk6dYXpIVd/AG6HW3jJglb+9\nCu8HPjQ6yBxaqnpEVbf722eAcrwr+UP5Pp8nbyhZ0e+eu0Xkbf/P5lD8iRkhXqe/UOBlEdnmX6Ud\nL4ap6hHwCgAw1HGeoML+OUZECoBpQDFx8D5H5IUQvsdW9KMQkVdFZFeUr2XAj4FLgKnAEeDfnYaN\nLtD0FyF0tapOx5vR9e/9bgnTO0L/ORaRHOB54Kuqetp1ns5EyRvK99gWRo9CVa8P0k5EfgL8ppfj\ndEeg6S/CRlUP+/8eFZEX8Lqp3nCbKpCPRGS4qh7x+3ePug7UGVX96Ox2GD/HItIPr4D+QlV/5e8O\n7fscLW9Y32M70u8i/8N21qeAXR21dSjI1BmhIiLZ/kkwRCQbuJFwvrfRtJ+GZCXwosMsgYT5c+xP\ny/44UK6qP2x3Vyjf547yhvU9ttE7XSQiT+H9uabAQeALZ/sZw8QfHvYf/GnqjFBfFS0iFwMv+DfT\ngF+GMbOIPA0swJtB8SPgn4BfA6uB0cAHwHJVDc2J0w4yLyCkn2MRmQtsAHYCbf7ub+H1k4fufT5P\n3hWE8D22om+MMUnEuneMMSaJWNE3xpgkYkXfGGOSiBV9Y4xJIlb0jTEmiVjRN8aYJGJF3xhjkogV\nfWOMSSL/H/AQ+WbiQp7tAAAAAElFTkSuQmCC\n", 629 | "text/plain": [ 630 | "" 631 | ] 632 | }, 633 | "metadata": {}, 634 | "output_type": "display_data" 635 | } 636 | ], 637 | "source": [ 638 | "amostra = my_norm.rvs(10000)\n", 639 | "ax.hist(amostra, normed=True, histtype='stepfilled', alpha=0.2)\n", 640 | "ax.legend(loc='best', frameon=False)\n", 641 | "plt.show()" 642 | ] 643 | }, 644 | { 645 | "cell_type": "markdown", 646 | "metadata": {}, 647 | "source": [ 648 | "Outro método que também está disponível para todas as distribuições implementadas na biblioteca `scipy.stats` é o método `fit`. Como o nome sugere este método ajusta a distribuição para um vetor de observações. " 649 | ] 650 | }, 651 | { 652 | "cell_type": "code", 653 | "execution_count": 82, 654 | "metadata": {}, 655 | "outputs": [ 656 | { 657 | "name": "stdout", 658 | "output_type": "stream", 659 | "text": [ 660 | "(10.482028224058263, 4.5548538593399748)\n", 661 | "(71.201643797121392, 10.459960255274375, 4.4904597272531337)\n" 662 | ] 663 | }, 664 | { 665 | "data": { 666 | "text/plain": [ 667 | "(9.8012505819540614, 2.6176037515189652)" 668 | ] 669 | }, 670 | "execution_count": 82, 671 | "metadata": {}, 672 | "output_type": "execute_result" 673 | } 674 | ], 675 | "source": [ 676 | "amostra = my_norm.rvs(100)\n", 677 | "print(sp.norm.fit(amostra)) # Ajustando a própria Normal\n", 678 | "print(sp.t.fit(amostra)) # Ajustando a distribuição t\n", 679 | "print(sp.cauchy.fit(amostra)) # Cauchy ou qq outra que seja adequada." 680 | ] 681 | }, 682 | { 683 | "cell_type": "markdown", 684 | "metadata": {}, 685 | "source": [ 686 | "Em geral as distribuições de probabilidade implementadas na biblioteca `scipy.stats` são vetorizadas. Assim, se o argumento for um objeto `ndarray` a função será aplicada em cada uma das entradas do `ndarray` e a saída também será um `ndarray`." 687 | ] 688 | }, 689 | { 690 | "cell_type": "code", 691 | "execution_count": 99, 692 | "metadata": {}, 693 | "outputs": [ 694 | { 695 | "data": { 696 | "text/plain": [ 697 | "array([ 0.00443185, 0.05399097, 0.24197072, 0.39894228, 0.24197072,\n", 698 | " 0.05399097, 0.00443185])" 699 | ] 700 | }, 701 | "execution_count": 99, 702 | "metadata": {}, 703 | "output_type": "execute_result" 704 | } 705 | ], 706 | "source": [ 707 | "a = np.array([-3,-2,-1,0,1,2,3])\n", 708 | "sp.norm.pdf(a, loc = 0, scale = 1)" 709 | ] 710 | }, 711 | { 712 | "cell_type": "markdown", 713 | "metadata": {}, 714 | "source": [ 715 | "Assim termino esta rápida introdução de como e onde as funções de probabilidades estão implementadas em python. Na sequência vou introduzir as principais idéias de otimização de funções em python.\n", 716 | "\n", 717 | "## Otimização\n", 718 | "\n", 719 | "Otimização de funções tem um papel central em inferência estatística. Uma vez que o estimador de maxima verossimilhança é o supremo da função de log-verossimilhança encontrar este ponto é crucial para o processo de inferência. O python através do modulo `scipy.optimization` fornece vários algoritmos para numericamente encontrar o mínimo/máximo de uma função pré-especificada. Este modulo também fornece algoritmos para solução de sistemas de equações não-lineares e minimização via métodos dos mínimos quadrados. Vamos ver alguns exemplos de como usar esta poderosa biblioteca. Como exemplo vou implementar a log-verossimilhança de um modelo de regressão linear simples." 720 | ] 721 | }, 722 | { 723 | "cell_type": "code", 724 | "execution_count": 219, 725 | "metadata": {}, 726 | "outputs": [ 727 | { 728 | "name": "stdout", 729 | "output_type": "stream", 730 | "text": [ 731 | "[ 0.955178 3.0605878 3.06253339 3.7901356 5.16958236 5.88972862\n", 732 | " 6.76677787 6.79734997 8.45627646 9.22860461]\n" 733 | ] 734 | } 735 | ], 736 | "source": [ 737 | "x = np.array(range(0,10))\n", 738 | "par = np.array([2,0.8,0.5])\n", 739 | "my_norm = sp.norm(loc = 0, scale = par[2])\n", 740 | "e = my_norm.rvs(len(x))\n", 741 | "mu = par[0] + par[1]*x\n", 742 | "y = mu + e\n", 743 | "print(y)" 744 | ] 745 | }, 746 | { 747 | "cell_type": "code", 748 | "execution_count": 233, 749 | "metadata": {}, 750 | "outputs": [ 751 | { 752 | "name": "stdout", 753 | "output_type": "stream", 754 | "text": [ 755 | "[ 1.48437886 0.85184602 -0.96076513]\n", 756 | "4.58212128641\n", 757 | "[ 1.4843624 0.85184735 -0.96072641]\n", 758 | "4.582121267138361\n", 759 | "[ 1.48436238 0.85184735 -0.96072644]\n", 760 | "4.582121267138369\n", 761 | "[ 1.48462153 0.85180644 -0.96136877]\n", 762 | "4.5821260605\n", 763 | "[ -2.98023224e-07 5.96046448e-07 -5.96046448e-07]\n", 764 | "[[ 5.12949827e-02 -7.98299503e-03 5.50750805e-04]\n", 765 | " [ -7.98299503e-03 1.78946275e-03 -9.84144963e-05]\n", 766 | " [ 5.50750805e-04 -9.84144963e-05 5.10698521e-02]]\n" 767 | ] 768 | } 769 | ], 770 | "source": [ 771 | "from scipy.optimize import minimize\n", 772 | "from math import exp, log\n", 773 | "\n", 774 | "def linreg(par, y, x):\n", 775 | " mu = par[0] + par[1]*x\n", 776 | " output = -sp.norm.logpdf(y, loc = mu, scale = exp(par[2])).sum()\n", 777 | " #print(output)\n", 778 | " return(output)\n", 779 | "\n", 780 | "# Avaliando a log-lik no ponto\n", 781 | "linreg(par = np.array([2.1788,0.7743, log(0.3817)]), y = y, x = x) \n", 782 | "\n", 783 | "# Valores iniciais\n", 784 | "par = np.array([2,0.8, log(2)])\n", 785 | "\n", 786 | "# Nelder-Mead\n", 787 | "res1 = minimize(linreg, par, method='nelder-mead', args = (y,x))\n", 788 | "print(res.x)\n", 789 | "print(res.fun)\n", 790 | "\n", 791 | "# Gradiente Conjugado\n", 792 | "res2 = minimize(linreg, par, method = 'CG', args = (y,x))\n", 793 | "print(res2.x)\n", 794 | "print(res2.fun)\n", 795 | "\n", 796 | "# BFGS\n", 797 | "res3 = minimize(linreg, par, method = 'BFGS', args = (y,x))\n", 798 | "print(res3.x)\n", 799 | "print(res3.fun)\n", 800 | "\n", 801 | "# Powell\n", 802 | "res4 = minimize(linreg, par, method = 'Powell', args = (y,x))\n", 803 | "print(res4.x)\n", 804 | "print(res4.fun)\n", 805 | "\n", 806 | "# Escore\n", 807 | "print(res3.jac)\n", 808 | "\n", 809 | "# Temos o inverso do hessiano\n", 810 | "print(res3.hess_inv)\n", 811 | "\n" 812 | ] 813 | } 814 | ], 815 | "metadata": { 816 | "kernelspec": { 817 | "display_name": "Python 3", 818 | "language": "python", 819 | "name": "python3" 820 | }, 821 | "language_info": { 822 | "codemirror_mode": { 823 | "name": "ipython", 824 | "version": 3 825 | }, 826 | "file_extension": ".py", 827 | "mimetype": "text/x-python", 828 | "name": "python", 829 | "nbconvert_exporter": "python", 830 | "pygments_lexer": "ipython3", 831 | "version": "3.5.2" 832 | } 833 | }, 834 | "nbformat": 4, 835 | "nbformat_minor": 2 836 | } 837 | -------------------------------------------------------------------------------- /aula-1-intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Encontro I\n", 8 | "\n", 9 | "## Objetivo\n", 10 | "\n", 11 | "O objetivo deste primeiro encontro é discutir aspectos básicos da linguagem python tais como:\n", 12 | "\n", 13 | "1. Instalação e configuração do ambiente de programação\n", 14 | " - Console python;\n", 15 | " - IPython e Spyder;\n", 16 | " - Anaconda (Jupyther notebook).\n", 17 | "2. Tipos de dados e estruturas\n", 18 | " - Tipos básicos de dados;\n", 19 | " - Operações e funções matemáticas básicas;\n", 20 | " - Estruturas básicas de dados;\n", 21 | " - Estruturas de controle;\n", 22 | " - Programação funcional;\n", 23 | " - Introdução ao NumPy;\n", 24 | "\n", 25 | "## 1. Instalação e configuração do ambiente de programação\n", 26 | "\n", 27 | "Todo sistema Linux já está equipado com uma ou geralmente duas versões da linguagem python. As versões mais comuns são a pyhton2.7 e a python3. Para iniciar o python no seu Linux basta abrir um terminal (CTRL + ALT + T) e digitar python. Caso queira verificar quais versões você tem instalado basta digitar python seguido da tecla TAB. Apesar de bastante simples esta forma de usar o python é pouco eficiente e uma série de ferramentas para auxiliar na produtividade e também no aprendizado da linguagem estão disponíveis.\n", 28 | "\n", 29 | "Neste primeiro contato com a linguagem vamos discutir outras duas formas de começar a programar em python. \n", 30 | "O programa [IPython](https://ipython.org/) é um poderoso prompt de comando para computação interativa desenvolvido para a linguagem python. IPython oferece suporte para visualização de dados interativa, sintaxe shell, tab completion e permite arquivar o histórico de código. Atualmente o projeto IPython cresceu e tornou-se um sistema multi linguagens fornecendo suporte para linguagens como Julia, R entre outras.\n", 31 | "\n", 32 | "Frequentemente o console IPython é usado em conjunto com o ambiente para desenvolvimento de computação ciêntífica [Spyder](https://pythonhosted.org/spyder/). O workflow é simples, o código python é escrito no editor Spyder e executado através do console IPython. O editor Spyder fornece recursos de edição avançados, testes interativos, debugging e introspection features. Este sistema parece mais adequado para o desenvolvimento de novos modulos e analises extensas.\n", 33 | "\n", 34 | "Dentro do escopo de data science a ferramenta [Jupyter](http://jupyter.org/) é muito popular. Jupyter notebook é uma aplicação web open-source que permite criar e compartilhar documentos que contêm código, equações, visualização e textos explicativos. Aplicações em geral envolvem, data cleaning e transformation, simulações numéricas, modelagem estatística, visualização de dados, machine learning e muito mais.\n", 35 | "\n", 36 | "Apesar de ser possível instalar cada uma das ferramentas mencionadas individualmente, uma forma mais simples de preparar o ambiente de programação python é instalar o pacote [Anaconda](https://anaconda.org/). Anaconda é uma distribuição open-source das linguagens python e R para processamento de dados em larga escala, predictive analytics e computação ciêntífica que objetiva simplificar o gerenciamento e desenvolvimento de pacotes. As versões dos pacotes são gerenciadas pelo sistema de gerenciamento de pacotes conda.\n", 37 | "\n", 38 | "Instalar o pacote Anaconda em distribuições Linux é muito fácil atráves da linha de comando do Linux. Basta seguir os seguintes passos:\n", 39 | "\n", 40 | " - Faça o download da versão Anaconda que deseja instalar. Neste exemplo vou usar a última versão (12/01/2018) disponível no endereço https://repo.continuum.io/archive/. Você também deve escolher entre a versão 2 ou 3 do python.\n", 41 | " Neste exemplo eu vou instalar a versão 3 para um computador 64 bits. Para fazer o download direto da linha de comando Linux vou usar o comando `wget`. Recomendo que faça todas essas operações no seu diretório `\\home`.\n", 42 | " \n", 43 | "```\n", 44 | "wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh\n", 45 | "\n", 46 | "```\n", 47 | " - Rode o script .sh para a instalação do Anaconda e siga as instruções. Na dúvida use a configuração default. Esse comando vai criar uma pasta chamada anaconda no diretório onde você está rodando a instalação.\n", 48 | " \n", 49 | "```\n", 50 | "bash Anaconda2-4.2.0-Linux-x86_64.sh -b -p ~/anaconda\n", 51 | "```\n", 52 | "\n", 53 | " - Precisamos colocar o Anaconda no caminho de busca para fácil acesso via a linha de comando Linux. Para isso incluímos o diretório do Anaconda em nosso arquivo `.bashrc`.\n", 54 | " \n", 55 | "```\n", 56 | "echo 'export PATH=\"~/anaconda/bin:$PATH\"' >> ~/.bashrc \n", 57 | "\n", 58 | "```\n", 59 | "\n", 60 | " - Finalmente, atualizamos o arquivo `.bashrc` e abrimos a aplicação Anaconda\n", 61 | " \n", 62 | "```\n", 63 | "source .bashrc\n", 64 | "anaconda-navigator\n", 65 | "\n", 66 | "```\n", 67 | "\n", 68 | " - Podemos atualizar todos os pacotes do Anaconda via o gerenciador de pacotes conda.\n", 69 | "\n", 70 | "```\n", 71 | "conda update conda\n", 72 | "\n", 73 | "```\n", 74 | "\n", 75 | "Assim, terminamos o processo de instalação do pacote Anaconda e estamos prontos para começar a programar em python. \n", 76 | "As instruções acima foram obtidas através do website (https://medium.com/@GalarnykMichael/install-python-on-ubuntu-anaconda-65623042cb5a).\n", 77 | "\n", 78 | "## 2. Tipos de dados e estruturas\n", 79 | "\n", 80 | "### Tipos básicos de dados\n", 81 | "\n", 82 | "A linguagem python é dinamicamente tipificada, isso significa que o interpretador do python vai reconhecer o tipo de objeto que o usuário esta declarando automaticamente. Os tipos de objetos fundamentais em python são: `integer`, `floats` e `string`.\n", 83 | "\n", 84 | "Para identificar o tipo de objeto em python usamos a comando `type()` e para imprimir o resultado de uma linha de código usamos o comando `print()` veja a seguir." 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 1, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "\n", 97 | "\n", 98 | "\n", 99 | "\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "a1 = 10 # Definimos a1 como o integer 10\n", 105 | "print(type(a1))\n", 106 | "\n", 107 | "a2 = 3 # Definimos a2 como o integer 3\n", 108 | "print(type(a2))\n", 109 | "\n", 110 | "a3 = 10.0 # Definimos a3 como o float 10.0\n", 111 | "print(type(a3))\n", 112 | "\n", 113 | "a4 = 3.0 # Definimos a4 como o float 3.0\n", 114 | "print(type(a4))" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "No python 3 a divisão de integer por integer já é automaticamente tipificada para float. \n", 122 | "Entretando, em versões mais antigas (python 2.7) essa conversão não é automática e requer o uso de pacotes específicos.\n", 123 | "Neste documento estamos usando a versão 3.6.2, então não precisamos nos preocupar com isso." 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 2, 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "name": "stdout", 133 | "output_type": "stream", 134 | "text": [ 135 | "3.3333333333333335\n", 136 | "\n", 137 | "3.3333333333333335\n", 138 | "\n", 139 | "3.3333333333333335\n", 140 | "\n" 141 | ] 142 | } 143 | ], 144 | "source": [ 145 | "b1 = a1/a2 # Divisão integer por integer -> float\n", 146 | "print(b1)\n", 147 | "print(type(b1)) \n", 148 | "\n", 149 | "b2 = a3/a4 # Divisão float por float -> float\n", 150 | "print(b2)\n", 151 | "print(type(b2))\n", 152 | "\n", 153 | "b3 = a1/a4 # Divisão integer por float -> float\n", 154 | "print(b3)\n", 155 | "print(type(b3))" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "Um aspecto muito interessante da linguagem python é que todos os objetos tem uma classe e toda classe tem uma série de atributos associados. Por exemplo, podemos acessar o número de bits usados pelo integer 10." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 3, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "4" 174 | ] 175 | }, 176 | "execution_count": 3, 177 | "metadata": {}, 178 | "output_type": "execute_result" 179 | } 180 | ], 181 | "source": [ 182 | "a1.bit_length()" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "Entretanto, objetos do tipo float obviamente não tem esse atributo. Você pode obter informações sobre float objetos usando o modulo `sys`." 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": 4, 195 | "metadata": {}, 196 | "outputs": [ 197 | { 198 | "data": { 199 | "text/plain": [ 200 | "sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)" 201 | ] 202 | }, 203 | "execution_count": 4, 204 | "metadata": {}, 205 | "output_type": "execute_result" 206 | } 207 | ], 208 | "source": [ 209 | "import sys \n", 210 | "sys.float_info" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "Internamente um float é representado como a razão entre dois integers. Para ver isso, objetos da class float tem um atributo." 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 5, 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "name": "stdout", 227 | "output_type": "stream", 228 | "text": [ 229 | "(10, 1)\n", 230 | "(3152519739159347, 9007199254740992)\n" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "print(a3.as_integer_ratio())\n", 236 | "c1 = 0.35\n", 237 | "print(c1.as_integer_ratio())" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "O último tipo básico de dado que veremos é o `strings`. `strings` em geral são usadas para representar textos os nomes e o python tem um rico ambiente para trabalhar com strings. Veja os exemplos abaixo" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 6, 250 | "metadata": {}, 251 | "outputs": [ 252 | { 253 | "name": "stdout", 254 | "output_type": "stream", 255 | "text": [ 256 | "\n" 257 | ] 258 | } 259 | ], 260 | "source": [ 261 | "t = \"isto é um objeto string\"\n", 262 | "print(type(t))" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "Objetos do tipo `str` tem um grande conjunto de atributos." 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 7, 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "Isto é um objeto string\n", 282 | "['isto', 'é', 'um', 'objeto', 'string']\n", 283 | "17\n", 284 | "isto|é|um|objeto|string\n", 285 | "o é um objeto \n", 286 | "3\n", 287 | "ISTO É UM OBJETO STRING\n", 288 | "isto é um objeto string\n" 289 | ] 290 | }, 291 | { 292 | "data": { 293 | "text/plain": [ 294 | "'m|i|n|h|a| |s|e|g|u|n|d|a| |s|t|r|i|n|g'" 295 | ] 296 | }, 297 | "execution_count": 7, 298 | "metadata": {}, 299 | "output_type": "execute_result" 300 | } 301 | ], 302 | "source": [ 303 | "print(t.capitalize()) # capitaliza a primeira letra\n", 304 | "print(t.split()) # corta por palavras\n", 305 | "print(t.find('string')) # index da primeira letra onde a palavra string começa\n", 306 | "print(t.replace(\" \", \"|\")) # troca espaço em branco por |\n", 307 | "print(t.strip('string')) # Remove uma palavra e/ou conjunto de strings\n", 308 | "print(t.count('o')) # Conta a ocorrência de uma string\n", 309 | "print(t.upper())\n", 310 | "print(t.lower())\n", 311 | "t2 = \"minha segunda string\"\n", 312 | "\"|\".join(t2) # Concatena strings\n" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "metadata": {}, 318 | "source": [ 319 | "Uma ferramenta muito poderosa quando trabalhando com strings é expressões regulares. Python oferece tais funcionalidades no modulo `re`." 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 8, 325 | "metadata": { 326 | "collapsed": true 327 | }, 328 | "outputs": [], 329 | "source": [ 330 | "import re" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "Suponha que temos um grande conjunto de dados que contêm uma série temporal e a respectiva informação de data e hora. Em geral, a informação da data aparece em um formato que o python não reconhece naturalmente. Entretanto, a informação pode geralmente ser descrita por uma expressão regular. Considere o seguinte objeto string" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 9, 343 | "metadata": {}, 344 | "outputs": [ 345 | { 346 | "name": "stdout", 347 | "output_type": "stream", 348 | "text": [ 349 | "\n", 350 | "'01/18/2014 13:00:00', 100, '1st';\n", 351 | "'01/18/2014 13:30:00', 110, '2nd';\n", 352 | "'01/18/2014 14:00:00', 120, '3rd';\n", 353 | "\n", 354 | "[\"'01/18/2014 13:00:00'\", \"'01/18/2014 13:30:00'\", \"'01/18/2014 14:00:00'\"]\n" 355 | ] 356 | } 357 | ], 358 | "source": [ 359 | "series = \"\"\"\n", 360 | "'01/18/2014 13:00:00', 100, '1st';\n", 361 | "'01/18/2014 13:30:00', 110, '2nd';\n", 362 | "'01/18/2014 14:00:00', 120, '3rd';\n", 363 | "\"\"\"\n", 364 | "print(series)\n", 365 | "\n", 366 | "dt = re.compile(\"'[0-9/:\\s]+'\")\n", 367 | "result = dt.findall(series)\n", 368 | "print(result)" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": {}, 374 | "source": [ 375 | "A string resultante pode ser convertida para objetos do tipo `datetime`." 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": 10, 381 | "metadata": {}, 382 | "outputs": [ 383 | { 384 | "name": "stdout", 385 | "output_type": "stream", 386 | "text": [ 387 | "2014-01-18 13:00:00\n", 388 | "\n" 389 | ] 390 | } 391 | ], 392 | "source": [ 393 | "from datetime import datetime\n", 394 | "pydt = datetime.strptime(result[0].replace(\"'\",\"\"), '%m/%d/%Y %H:%M:%S')\n", 395 | "print(pydt)\n", 396 | "print(type(pydt))" 397 | ] 398 | }, 399 | { 400 | "cell_type": "markdown", 401 | "metadata": {}, 402 | "source": [ 403 | "Com isso terminamos nossa discusão sobre tipos básicos de dados em python." 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": {}, 409 | "source": [ 410 | "### Operações e funções matemáticas básicas\n", 411 | "\n", 412 | "\n", 413 | "Em termos de operações matemáticas simples (soma, subtração, multiplicação e divisão) o python funciona exatamente como uma simples calculadora." 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": 11, 419 | "metadata": {}, 420 | "outputs": [ 421 | { 422 | "name": "stdout", 423 | "output_type": "stream", 424 | "text": [ 425 | "30\n", 426 | "\n", 427 | "30.0\n", 428 | "\n", 429 | "-10\n", 430 | "\n", 431 | "-10.0\n", 432 | "\n", 433 | "1480.0\n", 434 | "1480.0\n" 435 | ] 436 | } 437 | ], 438 | "source": [ 439 | "c1 = 10 + 20 # Soma de integer\n", 440 | "print(c1)\n", 441 | "print(type(c1))\n", 442 | "\n", 443 | "c2 = 10.0 + 20.0 # Soma de float\n", 444 | "print(c2)\n", 445 | "print(type(c2))\n", 446 | "\n", 447 | "c3 = 10 - 20 # Subtração de integer\n", 448 | "print(c3)\n", 449 | "print(type(c3))\n", 450 | "\n", 451 | "c4 = 10.0 - 20.0 # Subtração de float\n", 452 | "print(c4)\n", 453 | "print(type(c4))\n", 454 | "\n", 455 | "c5 = 30*50 + 80/4 - 20*2 # python respeita as operações matemáticas naturais mesmo sem o uso de parenteses.\n", 456 | "print(c5)\n", 457 | "\n", 458 | "# apesar de sempre recomendar o uso dos parenteses para facilitar a leitura de grandes equações\n", 459 | "c6 = (30*50) + (80/4) - (20*2) \n", 460 | "print(c6)" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": {}, 466 | "source": [ 467 | "Funções matemáticas especiais como logaritmo, exponencial, potênciação, funções trigonométricas, radiciação entre outras estão disponíveis através do modulo `math`. Ao carregar um modulo em python recomenda-se que apenas as funções que serão usadas sejam carregadas. Por exemplo, no código abaixo queremos calcular o logaritmo, a raiz quadrada, a exponencial e a potência de um número. Desta forma, importamos apenas estas funções do modulo `math`. Uma lista com todas as funções matemáticas disponíveis no modulo `math` pode ser encontrada no endereço (https://www.programiz.com/python-programming/modules/math). " 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 12, 473 | "metadata": {}, 474 | "outputs": [ 475 | { 476 | "name": "stdout", 477 | "output_type": "stream", 478 | "text": [ 479 | "2.302585092994046\n", 480 | "3.1622776601683795\n", 481 | "1.0\n", 482 | "100.0\n", 483 | "1000.0\n" 484 | ] 485 | } 486 | ], 487 | "source": [ 488 | "from math import log, sqrt, exp, pow\n", 489 | "\n", 490 | "print(log(10)) # Logaritmo de 10\n", 491 | "print(sqrt(10)) # raiz quadrada de 10\n", 492 | "print(exp(0)) # exponencial\n", 493 | "print(pow(10, 2)) # 10^2\n", 494 | "print(pow(10, 3)) # 10^3\n" 495 | ] 496 | }, 497 | { 498 | "cell_type": "markdown", 499 | "metadata": {}, 500 | "source": [ 501 | "### Estruturas básicas de dados\n", 502 | "\n", 503 | "Como uma regra geral, estruturas de dados são objetos que contêm possívelmente um grande número de outros objetos. Entre outros o python oferece as seguintes estruturas de dados:\n", 504 | "\n", 505 | " - `tuple`: Coleção arbitrária de objetos com poucos métodos disponíveis.\n", 506 | " - `list`: Coleção arbitrária de objetos com muitos métodos disponíveis.\n", 507 | " - `dict`: Objeto que armazenam valores-chaves.\n", 508 | " - `set`: Coleção não enumerada de objetos para outros objetos únicos.\n", 509 | "\n", 510 | "#### Tuples\n", 511 | "\n", 512 | "`tuple` é uma estrutura muito simples e com poucos recursos. A `tuple` é definida através de um conjunto de objetos entre parêntenses." 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "execution_count": 13, 518 | "metadata": {}, 519 | "outputs": [ 520 | { 521 | "name": "stdout", 522 | "output_type": "stream", 523 | "text": [ 524 | "\n" 525 | ] 526 | } 527 | ], 528 | "source": [ 529 | "t1 = (1, 2.5, 'tuple')\n", 530 | "print(type(t1))" 531 | ] 532 | }, 533 | { 534 | "cell_type": "markdown", 535 | "metadata": {}, 536 | "source": [ 537 | "Podemos selecionar elementos de uma `tuple` através de seus indices. \n", 538 | "Um aspecto importante é que o python usa zero-based numbering, ou seja, os índices começam em zero.\n", 539 | "Também podemos selecionar slices da `tuple` através de seus índices." 540 | ] 541 | }, 542 | { 543 | "cell_type": "code", 544 | "execution_count": 14, 545 | "metadata": {}, 546 | "outputs": [ 547 | { 548 | "name": "stdout", 549 | "output_type": "stream", 550 | "text": [ 551 | "2.5\n", 552 | "1\n", 553 | "\n", 554 | "(1,)\n", 555 | "(1, 2.5)\n", 556 | "tuple\n" 557 | ] 558 | } 559 | ], 560 | "source": [ 561 | "print(t1[1])\n", 562 | "print(t1[0])\n", 563 | "print(type(t1[2]))\n", 564 | "\n", 565 | "print(t1[0:1]) # Seleciona apenas o elemento na posição 0\n", 566 | "print(t1[0:2]) # Elemento da posição 0 e 1\n", 567 | "print(t1[-1]) # Índices negativos tbm funcionam" 568 | ] 569 | }, 570 | { 571 | "cell_type": "markdown", 572 | "metadata": {}, 573 | "source": [ 574 | "Para objetos do tipo `tuple` existem apenas dois métodos disponíveis: `count` e `index`. O método `count` conta as ocorrências de um certo valor e o método `index` retorno o índice que o valor apareceu pela primeira vez." 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": 15, 580 | "metadata": {}, 581 | "outputs": [ 582 | { 583 | "name": "stdout", 584 | "output_type": "stream", 585 | "text": [ 586 | "4\n", 587 | "7\n" 588 | ] 589 | } 590 | ], 591 | "source": [ 592 | "t2 = (1,2,2,2,3,3,3,5,5,5,5, \"tuple2\")\n", 593 | "print(t2.count(5))\n", 594 | "print(t2.index(5))" 595 | ] 596 | }, 597 | { 598 | "cell_type": "markdown", 599 | "metadata": {}, 600 | "source": [ 601 | "#### Lists\n", 602 | "\n", 603 | "Objetos do tipo `list` são muito mais flexíveis e poderosos do que `tuple`. Uma `list` é definida através de colchetes (brackets) e em termos de aplicações em estatística serão muito úteis. Entretando, a seleção de elementos e comportamentos básicas são similares aos de uma `tuple`." 604 | ] 605 | }, 606 | { 607 | "cell_type": "code", 608 | "execution_count": 16, 609 | "metadata": {}, 610 | "outputs": [ 611 | { 612 | "name": "stdout", 613 | "output_type": "stream", 614 | "text": [ 615 | "\n", 616 | "lista\n" 617 | ] 618 | } 619 | ], 620 | "source": [ 621 | "l1 = [1, 2.5, 'lista']\n", 622 | "print(type(l1))\n", 623 | "print(l1[2]) # Elemento posição 3" 624 | ] 625 | }, 626 | { 627 | "cell_type": "markdown", 628 | "metadata": {}, 629 | "source": [ 630 | "Podemos também converter objetos do tipo `tuple` para `list` usando a função `list()`." 631 | ] 632 | }, 633 | { 634 | "cell_type": "code", 635 | "execution_count": 17, 636 | "metadata": {}, 637 | "outputs": [ 638 | { 639 | "name": "stdout", 640 | "output_type": "stream", 641 | "text": [ 642 | "\n", 643 | "\n" 644 | ] 645 | } 646 | ], 647 | "source": [ 648 | "t1 = (1, 2.5, 'tuple')\n", 649 | "print(type(t1))\n", 650 | "t1 = list(t1)\n", 651 | "print(type(t1))" 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "Objetos do tipo `list` podem ser expandidos e/ou reducidos. Em python essas propriedades definem um objeto `mutable`. Assim, temos que um `list` é `mutable` enquanto que um `tuple` é `immutable`. Vamos ver algumas operações com objetos `list`." 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "execution_count": 18, 664 | "metadata": {}, 665 | "outputs": [ 666 | { 667 | "name": "stdout", 668 | "output_type": "stream", 669 | "text": [ 670 | "[1, 2.5, 'lista', [4, 3]]\n", 671 | "[1, 2.5, 'lista', [4, 3], 1.0, 1.5, 2.0]\n", 672 | "[1, 'insert', 2.5, 'lista', [4, 3], 1.0, 1.5, 2.0]\n", 673 | "[1, 'insert', 2.5, [4, 3], 1.0, 1.5, 2.0]\n", 674 | "[1, 'insert', 2.5, 1.0, 1.5, 2.0]\n", 675 | "[4, 3]\n" 676 | ] 677 | } 678 | ], 679 | "source": [ 680 | "# Acrescenta valores ao fim da list\n", 681 | "l1.append([4, 3])\n", 682 | "print(l1)\n", 683 | "# Extende a list ja existente\n", 684 | "l1.extend([1.0, 1.5, 2.0])\n", 685 | "print(l1)\n", 686 | "# Insere objetos em uma posição especifica\n", 687 | "l1.insert(1, 'insert')\n", 688 | "print(l1)\n", 689 | "# Remove a primeira occorência de um objeto\n", 690 | "l1.remove('lista')\n", 691 | "print(l1)\n", 692 | "# Remove e retorna o objeto em um indice\n", 693 | "p = l1.pop(3)\n", 694 | "print(l1)\n", 695 | "print(p)\n" 696 | ] 697 | }, 698 | { 699 | "cell_type": "markdown", 700 | "metadata": {}, 701 | "source": [ 702 | "Slicing refere-se a operação de quebrar o conjunto de dados em pequenas partes de interesse." 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "execution_count": 19, 708 | "metadata": {}, 709 | "outputs": [ 710 | { 711 | "data": { 712 | "text/plain": [ 713 | "[2.5, 1.0, 1.5]" 714 | ] 715 | }, 716 | "execution_count": 19, 717 | "metadata": {}, 718 | "output_type": "execute_result" 719 | } 720 | ], 721 | "source": [ 722 | "l1[2:5] # Elementos da terceira a quinta posição" 723 | ] 724 | }, 725 | { 726 | "cell_type": "markdown", 727 | "metadata": {}, 728 | "source": [ 729 | "Mais alguns exemplos de operações com objetos `list`." 730 | ] 731 | }, 732 | { 733 | "cell_type": "code", 734 | "execution_count": 20, 735 | "metadata": {}, 736 | "outputs": [ 737 | { 738 | "name": "stdout", 739 | "output_type": "stream", 740 | "text": [ 741 | "[1, 'insert', 2.5, 1.0, 1.5, 2.0]\n", 742 | "[1, 'insert', 5, 1.0, 1.5, 2.0]\n", 743 | "[1, 'insert', 5, 2, 1, 3, 2.0]\n", 744 | "1\n", 745 | "[1, 'insert', 5, 3, 2.0, 10]\n", 746 | "[1, 'insert', 5, 3, 2.0, 10, 10, 20, 30]\n", 747 | "[30, 20, 10, 10, 2.0, 3, 5, 'insert', 1]\n" 748 | ] 749 | }, 750 | { 751 | "ename": "TypeError", 752 | "evalue": "'<' not supported between instances of 'str' and 'int'", 753 | "output_type": "error", 754 | "traceback": [ 755 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 756 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 757 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0ml1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreverse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Do maior para o menor\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0ml1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Do menor para o maior\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 758 | "\u001b[0;31mTypeError\u001b[0m: '<' not supported between instances of 'str' and 'int'" 759 | ] 760 | } 761 | ], 762 | "source": [ 763 | "print(l1)\n", 764 | "l1[2] = 5 # substitui o elemento 3 pelo valor 5\n", 765 | "print(l1)\n", 766 | "l1[3:5] = [2,1,3] # Interessante\n", 767 | "print(l1)\n", 768 | "l1.append(10) # Junta o 10 na list\n", 769 | "print(l1.count(10)) # Conta o numero de ocorrência do 10\n", 770 | "del l1[3:5] # Deleta\n", 771 | "print(l1)\n", 772 | "l1.extend([10,20,30])\n", 773 | "print(l1)\n", 774 | "l1.reverse() # Do maior para o menor\n", 775 | "print(l1)\n", 776 | "l1.sort() # Do menor para o maior\n", 777 | "print(l1)" 778 | ] 779 | }, 780 | { 781 | "cell_type": "markdown", 782 | "metadata": {}, 783 | "source": [ 784 | "#### Dicts\n", 785 | "\n", 786 | "Objetos do tipo `dict` são dicionários `mutable` e permitem o armazenamento de dados através de `keys` que podem ser por exemplo, `string`. `dict` objetos não são ordenáveis. Um exemplo ilustra melhor a diferença entre `list` e `dict`." 787 | ] 788 | }, 789 | { 790 | "cell_type": "code", 791 | "execution_count": null, 792 | "metadata": {}, 793 | "outputs": [], 794 | "source": [ 795 | "d = {\n", 796 | " 'Nome' : 'Wagner Hugo Bonat',\n", 797 | " 'País' : 'Brasil',\n", 798 | " 'Profissão' : 'Professor',\n", 799 | " 'Idade' : 32\n", 800 | "}\n", 801 | "print(type(d))\n", 802 | "print( d['Nome'], d['Idade'] )\n", 803 | "\n", 804 | "d.keys() # Acessa o nome das chaves\n", 805 | "\n", 806 | "d.values() # Acessa os valores" 807 | ] 808 | }, 809 | { 810 | "cell_type": "markdown", 811 | "metadata": {}, 812 | "source": [ 813 | "Existem uma séries de métodos para iterar em objetos da classe `dict`. Veremos detalhes na seção de estruturas de controle e programação funcional." 814 | ] 815 | }, 816 | { 817 | "cell_type": "markdown", 818 | "metadata": {}, 819 | "source": [ 820 | "#### Sets\n", 821 | "\n", 822 | "A última estrutura de dados básica que vamos discutir é a estrutura `set`. A estrutura `set` implementa a teoria dos conjuntos atráves de simples objetos. Ela pode ser útil para explicar conceitos de probabilidade. Vamos ver alguns conceitos simples de probabilidade usando a estrutura `set`em python." 823 | ] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "execution_count": null, 828 | "metadata": {}, 829 | "outputs": [], 830 | "source": [ 831 | "s = set(['A','B', 'AB', 'BA', 'B', 'BA']) # Note que objeto repetidas são automaticamente descartados\n", 832 | "print(s)\n", 833 | "t = set(['B', 'BB', 'AA', 'A'])\n", 834 | "print(t)\n", 835 | "\n", 836 | "print(s.union(t)) # União dos conjuntos\n", 837 | "print(s.intersection(t)) # Intersecção\n", 838 | "print(s.difference(t)) # Em s mas não em t\n", 839 | "print(t.difference(s)) # Em t mas não em s\n", 840 | "print(s.symmetric_difference(t)) # em s ou t mas não em ambos\n" 841 | ] 842 | }, 843 | { 844 | "cell_type": "markdown", 845 | "metadata": {}, 846 | "source": [ 847 | "### Estruturas de controle\n", 848 | "\n", 849 | "Estruturas de controle são a forma que o programador tem de controlar o que e para quais objetos o código vai funcionar. Apesar de uso geral, nesta seção vou focar mais em objetos do tipo `list`. \n", 850 | "O exemplo a seguir define uma lista com 6 valores e imprime o quadrado os valores entre os índices 2 e 5. \n", 851 | "Em python a indentação é parte da linguagem, então observe com atenção os espaços em branco na segunda linha.\n", 852 | "Note ainda que no segundo loop for o índice teve que ser apropriadamente restrito.\n", 853 | "Esta estrutura de looping é muito útil e fácil de usar. " 854 | ] 855 | }, 856 | { 857 | "cell_type": "code", 858 | "execution_count": null, 859 | "metadata": {}, 860 | "outputs": [], 861 | "source": [ 862 | "l2 = [1,2,3,4,5,6]\n", 863 | "print(l2[2:5])\n", 864 | "\n", 865 | "for i in l2[2:5]:\n", 866 | " print(l2[i] ** 2)\n", 867 | "\n", 868 | "for i in l2:\n", 869 | " print(l2[i-1])" 870 | ] 871 | }, 872 | { 873 | "cell_type": "markdown", 874 | "metadata": {}, 875 | "source": [ 876 | "Entretando, podemos usar o mais tradicional loop baseado em um contador (como usual em linguagens com C)." 877 | ] 878 | }, 879 | { 880 | "cell_type": "code", 881 | "execution_count": null, 882 | "metadata": {}, 883 | "outputs": [], 884 | "source": [ 885 | "r = range(0, 6, 1)\n", 886 | "\n", 887 | "for r in range(2, 5):\n", 888 | " print(l2[r] ** 2)" 889 | ] 890 | }, 891 | { 892 | "cell_type": "markdown", 893 | "metadata": {}, 894 | "source": [ 895 | "Python também oferece as típicas estruturas de controle condicional `if`, `elif` e `else`. O uso é similar a outras linguagens." 896 | ] 897 | }, 898 | { 899 | "cell_type": "code", 900 | "execution_count": null, 901 | "metadata": {}, 902 | "outputs": [], 903 | "source": [ 904 | "for i in range(1, 10):\n", 905 | " if i % 2 == 0: # % resto da divisão \n", 906 | " print(\"%d é par\" % i)\n", 907 | " elif i % 3 == 0:\n", 908 | " print(\"%d é múltiplo de 3\" % i)\n", 909 | " else:\n", 910 | " print(\"%d é ímpar\" % i)\n", 911 | " " 912 | ] 913 | }, 914 | { 915 | "cell_type": "markdown", 916 | "metadata": {}, 917 | "source": [ 918 | "O última estrutura de controle que vamos ver será o `while`." 919 | ] 920 | }, 921 | { 922 | "cell_type": "code", 923 | "execution_count": null, 924 | "metadata": {}, 925 | "outputs": [], 926 | "source": [ 927 | "total = 0\n", 928 | "while total < 100:\n", 929 | " total += 1\n", 930 | "print(total)" 931 | ] 932 | }, 933 | { 934 | "cell_type": "markdown", 935 | "metadata": {}, 936 | "source": [ 937 | "Uma especialidade do python é a chamada `list comprehensions`. Ao invés de rodar sobre objetos tipo `list` já existentes, esta abordagem gerá a `list` via loops em uma forma muito compacta." 938 | ] 939 | }, 940 | { 941 | "cell_type": "code", 942 | "execution_count": null, 943 | "metadata": {}, 944 | "outputs": [], 945 | "source": [ 946 | "m = [i ** 2 for i in range(5)]\n", 947 | "print(m)" 948 | ] 949 | }, 950 | { 951 | "cell_type": "markdown", 952 | "metadata": {}, 953 | "source": [ 954 | "Em certo sentido a abordagem de `list comprehensions` já fornece algo como vetorização de código, que será discutida em detalhes na seção Vetorização de código.\n", 955 | "\n", 956 | "### Programação funcional\n", 957 | "\n", 958 | "Python oferece muitas ferramentas para programação funcional *functional programming*. Programação funcional refere-se ao processo de aplicar uma função a um conjunto de entradas, em geral em python a um objeto do tipo `list`. Entre estas ferramentas estão `filter`, `map` e `reduce`. Entretando, para começar precisamos definir uma função em python. \n", 959 | "\n", 960 | "Para começar vamos implementar a distribuição de probabilidade mais usada em estatística, ou seja, a distribuição Gaussiana. A função densidade probabilidade da distribuição Gaussiana é dada por\n", 961 | "\n", 962 | "$$ f(y;\\mu, \\sigma^2) = \\frac{1}{\\sqrt{2 \\pi \\sigma^2}} \\exp\\left \\{- \\frac{1}{2\\sigma^2} (y - \\mu)^2 \\right \\}, $$\n", 963 | "onde $ y, \\mu \\in \\Re$ e $\\sigma^2 > 0$. Nesta parametrização tem-se que $E(Y) = \\mu$ e $Var(Y) = \\sigma^2$.\n", 964 | "\n", 965 | "Para implementar tal função em python, primeiro identificamos quais argumentos serão necessários. Neste caso são três $y$, $\\mu$ e $\\sigma^2$. Na sequência identificamos quais as funções matemática especiais envolvidas na função, no caso da distribuição Gaussiana temos, raiz quadrada, constant $\\pi$, potência e exponencial (`sqrt`, `pi`, `pow` e `exp`) todas estão disponíveis através do módulo `math`. Vamos ver como fica a distribuição Gaussiana implementada em python." 966 | ] 967 | }, 968 | { 969 | "cell_type": "code", 970 | "execution_count": null, 971 | "metadata": {}, 972 | "outputs": [], 973 | "source": [ 974 | "from math import sqrt, pi, exp, pow\n", 975 | "\n", 976 | "def dnorm(y, mu = 0, sigma2 = 1):\n", 977 | " output = (1/(sqrt(2 * pi * sigma2)))*exp( - (1/(2 * sigma2)) * pow(y - mu, 2) )\n", 978 | " return output\n", 979 | "\n", 980 | "print(dnorm(y = 0))\n", 981 | "print(dnorm(y = 0, mu = 10, sigma2 = 2))" 982 | ] 983 | }, 984 | { 985 | "cell_type": "markdown", 986 | "metadata": {}, 987 | "source": [ 988 | "Suponha que queremos aplicar a função `dnorm` para uma `list` de objetos. Podemos fazer isso usando um loop for como na seção anterior. " 989 | ] 990 | }, 991 | { 992 | "cell_type": "code", 993 | "execution_count": null, 994 | "metadata": {}, 995 | "outputs": [], 996 | "source": [ 997 | "# Tradicional loop for\n", 998 | "numbers = [-3, -2, -1, 0, 1, 2, 3]\n", 999 | "for i in numbers:\n", 1000 | " print(dnorm(y = i, mu = 0, sigma2 = 1))" 1001 | ] 1002 | }, 1003 | { 1004 | "cell_type": "markdown", 1005 | "metadata": {}, 1006 | "source": [ 1007 | "De uma forma mais elegante podemos usar programação funcional através da função `map` em python. " 1008 | ] 1009 | }, 1010 | { 1011 | "cell_type": "code", 1012 | "execution_count": null, 1013 | "metadata": {}, 1014 | "outputs": [], 1015 | "source": [ 1016 | "print(list(map(dnorm, numbers)))\n", 1017 | "print(list(map(dnorm, numbers, [10,10,10,10,10,10,10], [1,1,1,1,1,1,1]))) # Um pouco incoveniente mais funciona!" 1018 | ] 1019 | }, 1020 | { 1021 | "cell_type": "markdown", 1022 | "metadata": {}, 1023 | "source": [ 1024 | "Para funções simples (em geral de uma linha) podemos usar funções anônimas ou como são chamadas em python `lambda functions`. " 1025 | ] 1026 | }, 1027 | { 1028 | "cell_type": "code", 1029 | "execution_count": null, 1030 | "metadata": {}, 1031 | "outputs": [], 1032 | "source": [ 1033 | "list(map(lambda x: x ** 2, numbers))" 1034 | ] 1035 | }, 1036 | { 1037 | "cell_type": "markdown", 1038 | "metadata": {}, 1039 | "source": [ 1040 | "Funções também podem ser usadas para filtrar valores de interesse. Suponha que queremos obter apenas os valores pares de uma grande `list` de números. Primeiro definimos a função que faz a seleção e depois aplicamos ela a cada elemento da nossa lista de valores filtrando os que temos interesse." 1041 | ] 1042 | }, 1043 | { 1044 | "cell_type": "code", 1045 | "execution_count": null, 1046 | "metadata": {}, 1047 | "outputs": [], 1048 | "source": [ 1049 | "def even(x):\n", 1050 | " return x % 2 == 0\n", 1051 | "\n", 1052 | "list(filter(even, range(15)))" 1053 | ] 1054 | }, 1055 | { 1056 | "cell_type": "markdown", 1057 | "metadata": {}, 1058 | "source": [ 1059 | "Finalmente, podemos reduzir o conjunto de dados aplicando alguma função em todos os elementos da `list`. Um exemplo é a soma cumulativa dos objetos em uma `list`. Importante ressaltar que a função `reduce` no python 3.0 é parte do modulo functools, e portante precisa ser importada explicitamente." 1060 | ] 1061 | }, 1062 | { 1063 | "cell_type": "code", 1064 | "execution_count": null, 1065 | "metadata": {}, 1066 | "outputs": [], 1067 | "source": [ 1068 | "from functools import reduce\n", 1069 | "\n", 1070 | "reduce(lambda x, y: x + y, range(10))" 1071 | ] 1072 | }, 1073 | { 1074 | "cell_type": "markdown", 1075 | "metadata": {}, 1076 | "source": [ 1077 | "Podemos também usar as funções em conjunto ganhando ainda mais flexibilidade. Por exemplo, suponha que queremos somar apenas os números positivos de uma sequência de números em uma `list`." 1078 | ] 1079 | }, 1080 | { 1081 | "cell_type": "code", 1082 | "execution_count": null, 1083 | "metadata": {}, 1084 | "outputs": [], 1085 | "source": [ 1086 | "reduce(lambda x, y: x + y, filter(even, range(20)))" 1087 | ] 1088 | }, 1089 | { 1090 | "cell_type": "markdown", 1091 | "metadata": {}, 1092 | "source": [ 1093 | "É considerado uma boa prática evitar loop for em Python tanto quanto possível. `list comprehension` e `functional programming` atráves de funções como `map`, `filter` e `reduce` oferecem um código mais compacto e em geral de fácil leitura. \n", 1094 | "\n", 1095 | "### Estrutura de dados NumPy\n", 1096 | "\n", 1097 | "As seções anteriores mostraram que o python oferece algumas estruturas flexíveis para o armazenamento e manipulação de dados básicos. Em particular, `list` são muito úteis para trabalhar com dados e analises estatística. Entretando, quando trabalhando com analise de dados reais, tem-se a necessidade para operações de alta performance em dados com estruturas especiais. Uma das estruturas mais importantes é o `array`. `array` geralmente estruturam outros objetos em linhas e colunas. \n", 1098 | "\n", 1099 | "Assuma que estamos trabalhando com números (os conceitos funcionam também para `string`). No caso mais simples, um `array` unidimensional representa um vetor de números reais representados internamente como `float`. De forma mais geral um `array` representa uma matrix $i \\times j$ de elementos. O mais interessantes sobre `array` é que estes conceitos generalizam para cubos $i \\times j \\times k$ de elementos, bem como, para n-dimensionais arrays de corpo $i \\times j \\times k \\times l \\times, \\ldots$.\n", 1100 | "\n", 1101 | "De forma geral, matrizes são de extrema importância em estatística, assim precisamos de uma forma simples e eficiente de trabalhar ao menos com `arrays` bidimensionais. É neste ponto que a biblioteca `NumPy` é de extrema importância dentro do ambiente python.\n", 1102 | "\n", 1103 | "Antes de introduzir o modelo `NumPy` vamos discutir como `array` podem ser obtidos como uma `list` de `list`." 1104 | ] 1105 | }, 1106 | { 1107 | "cell_type": "code", 1108 | "execution_count": null, 1109 | "metadata": {}, 1110 | "outputs": [], 1111 | "source": [ 1112 | "v = [0.5, 1, 1.5, 2, 2.5, 3] # vector of numbers\n", 1113 | "m = [v, v, v] # matriz\n", 1114 | "print(m)\n", 1115 | "m[1][0] # Segunda linha primeiro elemento" 1116 | ] 1117 | }, 1118 | { 1119 | "cell_type": "markdown", 1120 | "metadata": {}, 1121 | "source": [ 1122 | "Podemos também ter um cubo de números, ou um `array` tridimensional." 1123 | ] 1124 | }, 1125 | { 1126 | "cell_type": "code", 1127 | "execution_count": null, 1128 | "metadata": {}, 1129 | "outputs": [], 1130 | "source": [ 1131 | "v1 = [0.5, 1.5]\n", 1132 | "v2 = [1, 2]\n", 1133 | "m = [v1,v2]\n", 1134 | "c = [m, m]\n", 1135 | "print(c)\n", 1136 | "print(c[1])\n", 1137 | "print(c[1][0])\n", 1138 | "print(c[1][0][1])" 1139 | ] 1140 | }, 1141 | { 1142 | "cell_type": "markdown", 1143 | "metadata": {}, 1144 | "source": [ 1145 | "É importante enfatizar que combinar elementos como feito anteriormente funciona como `reference pointers` para os objetos anteriores. Essa idéia fica clara através de um exemplo." 1146 | ] 1147 | }, 1148 | { 1149 | "cell_type": "code", 1150 | "execution_count": null, 1151 | "metadata": {}, 1152 | "outputs": [], 1153 | "source": [ 1154 | "v = [0.5, 0.75, 1.0, 1.5, 2.0]\n", 1155 | "m = [v, v, v]\n", 1156 | "print(m)\n", 1157 | "\n", 1158 | "v[0] = 'python'\n", 1159 | "print(m)" 1160 | ] 1161 | }, 1162 | { 1163 | "cell_type": "markdown", 1164 | "metadata": {}, 1165 | "source": [ 1166 | "Para evitar este comportamento usamos a função `deepcopy` do modulo `copy`." 1167 | ] 1168 | }, 1169 | { 1170 | "cell_type": "code", 1171 | "execution_count": null, 1172 | "metadata": {}, 1173 | "outputs": [], 1174 | "source": [ 1175 | "from copy import deepcopy\n", 1176 | "v = [0.5, 0.75, 1.0, 1.5, 2.0]\n", 1177 | "m = 3 * [deepcopy(v), ]\n", 1178 | "print(m)\n", 1179 | "v[0] = 'python'\n", 1180 | "print(m)" 1181 | ] 1182 | }, 1183 | { 1184 | "cell_type": "markdown", 1185 | "metadata": {}, 1186 | "source": [ 1187 | "Apesar de flexível esta forma de criar `array` não é muito útil para aplicações em estatística, uma vez que, o ferramental de álgebra linear não está disponível para este tipo de objetos. Por exemplo, a simples multiplicação de um escalar por um vetor não é definida para objetos do tipo `list` em python." 1188 | ] 1189 | }, 1190 | { 1191 | "cell_type": "code", 1192 | "execution_count": null, 1193 | "metadata": {}, 1194 | "outputs": [], 1195 | "source": [ 1196 | "v = [0.5, 1, 1.5] # vetor\n", 1197 | "n = 2 # escalar\n", 1198 | "n*v # Repete a list duas vezes, ao invés da multiplicação de escalar por vetor" 1199 | ] 1200 | }, 1201 | { 1202 | "cell_type": "markdown", 1203 | "metadata": {}, 1204 | "source": [ 1205 | "Isso mostra que precisamos de um tipo de objeto mais especializado que automaticamente entenda operações de álgebra linear e similares. A *library* `NumPy` traz este tipo de objeto que é chamada genericamente de `ndarray`." 1206 | ] 1207 | }, 1208 | { 1209 | "cell_type": "code", 1210 | "execution_count": null, 1211 | "metadata": {}, 1212 | "outputs": [], 1213 | "source": [ 1214 | "import numpy as np\n", 1215 | "a = np.array([0, 0.5, 1.0, 1.5, 2.0])\n", 1216 | "print(a)\n", 1217 | "print(type(a))" 1218 | ] 1219 | }, 1220 | { 1221 | "cell_type": "markdown", 1222 | "metadata": {}, 1223 | "source": [ 1224 | "A principal vantagem deste tipo de objeto é a grande quantidade de métodos disponíveis. Alguns exemplos," 1225 | ] 1226 | }, 1227 | { 1228 | "cell_type": "code", 1229 | "execution_count": null, 1230 | "metadata": {}, 1231 | "outputs": [], 1232 | "source": [ 1233 | "print(a.sum()) # Soma todos os elementos\n", 1234 | "print(a.std()) # Erro padrão\n", 1235 | "print(a.cumsum()) # Soma acumulada\n", 1236 | "print(a.shape)\n", 1237 | "print(a.size)" 1238 | ] 1239 | }, 1240 | { 1241 | "cell_type": "markdown", 1242 | "metadata": {}, 1243 | "source": [ 1244 | "Uma lista completa de todos os métodos disponíveis para `ndarray` objetos pode ser obtida [aqui](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.html). \n", 1245 | "Do ponto de vista de aplicações em estatística a grande vantagem de objetos do tipo `ndarray` é que operações matriciais são reconhecidas. Aqui vamos apresentar apenas o básico, no decorrer da discussão teremos um encontro dedicado especificamente a álgebra linear usando `NumPy`." 1246 | ] 1247 | }, 1248 | { 1249 | "cell_type": "code", 1250 | "execution_count": null, 1251 | "metadata": {}, 1252 | "outputs": [], 1253 | "source": [ 1254 | "a = [1, 2] # Python basic\n", 1255 | "b = [3, 4]\n", 1256 | "print(a + b) # Concatena\n", 1257 | "\n", 1258 | "a = np.array([1, 2]) # Usando NumPy\n", 1259 | "print(a*2) # Multiplicação por escalar\n", 1260 | "\n", 1261 | "b = np.array([3, 4])\n", 1262 | "print(a + b) # Soma de vetores\n", 1263 | "\n", 1264 | "# Matrix 2 x 2\n", 1265 | "c = np.matrix([ [1,2], [3,4] ])\n", 1266 | "print(c)\n", 1267 | "print(c.shape)\n", 1268 | "\n", 1269 | "c2 = np.matrix([ [4,5], [6, 7]])\n", 1270 | "print(c2[0,:]) # Primeira linha\n", 1271 | "print(c2[:,0]) # Primeira coluna\n", 1272 | "\n", 1273 | "# Multiplicacao de matrizes\n", 1274 | "np.dot(c,c2)" 1275 | ] 1276 | }, 1277 | { 1278 | "cell_type": "markdown", 1279 | "metadata": {}, 1280 | "source": [ 1281 | "Uma outra especialidade da biblioteca `NumPy` são os `array` estruturados. Essa opção permite que em um mesmo `array` sejam armazenados diferentes tipos de dados por coluna. Porém, vamos deixar esta discussão para um encontro específico." 1282 | ] 1283 | } 1284 | ], 1285 | "metadata": { 1286 | "kernelspec": { 1287 | "display_name": "Python 3", 1288 | "language": "python", 1289 | "name": "python3" 1290 | }, 1291 | "language_info": { 1292 | "codemirror_mode": { 1293 | "name": "ipython", 1294 | "version": 3 1295 | }, 1296 | "file_extension": ".py", 1297 | "mimetype": "text/x-python", 1298 | "name": "python", 1299 | "nbconvert_exporter": "python", 1300 | "pygments_lexer": "ipython3", 1301 | "version": "3.5.2" 1302 | } 1303 | }, 1304 | "nbformat": 4, 1305 | "nbformat_minor": 2 1306 | } 1307 | --------------------------------------------------------------------------------