<jupyter_start><jupyter_text>*Datasets*Os *datasets* (conjuntos de dados) são o principal insumo dos processos de análise de dados e de ciência de dados. Eles são representados normalmente por dados tabulares em formato de planilha onde as linhas são os registros dos acontecimentos e as colunas são as características desses acontecimentos.Existem variadas formas de salvar um *dataset*, na área de processamento de dados as formas mais comuns envolvem salvar os dados em arquivos nos formatos `.xlsx`, `.csv` ou `.tsv`. Embora também seja possível trabalhar com dados guardados em bases de dados, obtendo as informações por meio de consultas a base.Neste `notebook` será apresentado o carregamento do *dataset*  [*DETECTING INDIVIDUAL AND COMBINED FINGERS MOVEMENTS*](https://www.rami-khushaba.com/electromyogram-emg-repository.html).  Detalhes do *dataset*>É uma boa prática prover um resumo do *dataset* utilizado, pontuando características importantes para o processo da analise dos dados, explicando como ele está estruturado e colocando as devidas refências quando aplicável.*dataset*: DETECTING INDIVIDUAL AND COMBINED FINGERS MOVEMENTS \[1\]Dez voluntários, com idade entre 20 e 35 anos foram recrutados para realizarem movimentos com os dedos.Os voluntários possuem os membros normais e sem desordem neurológica ou muscular. Os voluntários estavam sentados em uma poltrona com o braço apoiado e fixado em uma posição, para evitar efeitos de posições diferentes do membro. Os dados foram coletados utilizando **2 canais EMG** e processados pelo software Bagnoli Desktop EMG Systems da Delsys Inc. Os sinals EMG coletados dos eletrodos foram amplificados utilizando o amplificador Delsys Bagnoli-8 para um ganho total de 1000. Um conversor analógico digital de 12 bits foi utilizado para amostrar o sinal a **4000 Hz**.Os sinais EMG foram filtrados por um filtro passa-banda entre 20 e 450 Hz com um filtro *notch* para remover as faixas de 50 Hz provenientes da rede elétrica.Sinais de dez classes de movimentos de dedos, individuais e combinados, foram coletados. Para cada classe foram realizados seis ensaios.- Flexão individual:  - Polegar (T-T)  - Indicador (I-I)  - Médio (M-M)  - Anular (R-R)  - Minimo (L-L)- Flexão combinada:  - Polegar-Indicador (T-I)  - Polegar-Médio (T-M)  - Polegar-Anular (T-R)  - Polegar-Minimo (T-L)  - Punho fechado (HC)Os arquivos do *dataset* estão organizados da seguinte forma: há uma pasta para cada voluntário, o padrão de nomenclatura das pastas é `EMG-S`, por exemplo, para o voluntário 1 temos a pasta `EMG-S1`, para o voluntário 2 temos a pasta `EMG-S2`, e assim sucessivamente.Dentro de cada pasta há um arquivo `.csv` para cada coleta. São seis ensaios por classe, totalizando 60 arquivos `.csv`. Cada arquivo possui duas colunas, sem cabeçalho. Cada coluna representa os dados de um canal EMG. A nomenclatura dos arquivos segue o padrão `.csv`, por exemplo, a primeira coleta do arquivo da classe Polegar, representado por T-T, tem o nome `T-T1.csv`, o arquivo da segunda coleta tem o nome `T-T2.csv`, e assim sucessivamente.\[1\] <NAME>, <NAME>, <NAME>, and <NAME>, "Toward Improved Control of Prosthetic Fingers Using Surface Electromyogram (EMG) Signals", Expert Systems with Applications, vol 39, no. 12, pp. 10731–10738, 2012.Disponível em: (https://www.rami-khushaba.com/electromyogram-emg-repository.html)>Com a análise dos detalhes do *dataset* utilizado descobrimos dados importantes, como a frêquencia de amostragem e o fato de que esse *dataset* já teve seus dados filtratos para remoção de interferências da rede elétrica. Estas informações serão úteis em etapas posteriores.  Carregando o *dataset*O carregamento do *dataset* varia conforme o formato que os dados estão armazenados e estruturados. Vimos que temos os dados no formato `.csv`, utilizaremos a biblioteca [pandas](https://pandas.pydata.org) para realizar o carregamento e a biblioteca [numpy](https://numpy.org) para organizar os dados em arrays para facilitar a manipulação destes dados futuramente.<jupyter_code>import pandas as pd

# carrega um arquivo .csv para um pandas dataframe
t_t1 = pd.read_csv('./datasets/khushaba/EMG-S2/T-T1.csv', delimiter=',', header=None)
# converte o dataframe do pandas para um numpy array
t_t1 = t_t1.to_numpy()

# imprime o shape do numpy array
print(t_t1.shape)
# neste exemplo devemos ter um shape de (20000, 2), 20000 linhas e 2 colunas, onde cada coluna é um canal.<jupyter_output>(20000, 2)<jupyter_text>Realizamos o carregamento de um ensaio de uma classe de um voluntário e o tranformamos em um numpy array. É preciso carregar todas os ensaios de cada classe, podemos usufluir do padrão da nomenclaruta dos arquivos e criar um laço de repetição para o carregamento destes dados<jupyter_code>import numpy as np

classes = ['T-I','T-L','T-M','T-R','T-T','HC-','I-I','L-L','M-M','R-R']

# variável para armazenar os dados das classes
data = []

for classe in classes:
    # variável para armazear os dados dos ensaios
    trials = []
    for i in range(1, 7): # de 1 a 6 (Qt. de ensaios)
        # carrega o arquivo .csv para um pandas dataframe
        dataframe = pd.read_csv(f'./datasets/khushaba/EMG-S1/{classe}{i}.csv', delimiter=',', header=None)
        
        # converte os dados do um ensaio para numpy array e o adiciona na lista de ensaios
        trials.append(dataframe.to_numpy())
    
    # adiciona os ensaios de uma classe a lista de dados das classes
    data.append(trials)

# transforma os dados das classes em um numpy array
data = np.array(data)

# imprime o shape do numpy array
print(f'{data.shape} - (classes, ensaios, linhas, canais)')
# neste momento devemos ter um shape de (10, 6, 20000, 2), sendo 10 classes, 6 ensaios, 20000 linhas e 2 canais<jupyter_output>(10, 6, 20000, 2) - (classes, ensaios, linhas, canais)<jupyter_text>O shape atual dos dados não é adequado para os processamentos posterior que serão aplicados sobre eles, o ideal é que as linhas com os dados dos eletrodos estejam no último eixo do numpy array, para corrigir isso podemos utilizar a função *swapaxes* do próprio numpy array<jupyter_code># troca os eixos 2 e 3 do numpy array
data = data.swapaxes(2, 3)

# imprime o shape do numpy array
print(f'{data.shape} - (classes, ensaios, canais, linhas)')
# neste momento devemos ter um shape de (10, 6, 2, 2000), sendo 10 classes, 6 ensaios, 2 canais e 20000 linhas<jupyter_output>(10, 6, 2, 20000) - (classes, ensaios, canais, linhas)<jupyter_text>**Desafio:** Utilizando o padrão de nomenclatura das pastas que guardam os arquivos do *dataset*, implemente uma função que realizará o carregamento dos dados para todas os voluntários do *dataset*. Essa função deve retornar um dicionário python cuja as chaves sejam os voluntários e o valor de cada chave seja um `numpy array` representando os dados daquele voluntário.<jupyter_code># Sua função aqui<jupyter_output><empty_output><jupyter_text>Melhorando o carregamento dos dadosDurante o desenvolvimento de uma analise de dados é comum precisar rodar o código várias vezes, sendo ncessário carregar sempre os dados dos arquivos do *dataset* e realizar a conversão para numpy array.É possível, entretando, salvar os dados do numpy array em um arquivo `.npy`, desta forma sempre que o código for executado podemos verificar se o arquivo já existe e realizar um rápido carregamento dos dados já no formato numpy array, sem a necessidade de carregar os arquivos do *dataset* e realizar conversões.<jupyter_code># Salva o numpy array 'data' em './lib/data/converted/s1.npy'
np.save('./datasets/khushaba/s2', data)
# print(np.load('./datasets/khushaba/s2.npy'))
# Lembre-se de que o diretório deve existir, caso contrário uma exceção será lançada<jupyter_output><empty_output><jupyter_text>**Desafio:** Implemente uma função que carregue os dados de todos os voluntários do *dataset*. Para cada voluntário a função deve verificar a existencia de um arquivo `.npy`, caso o arquivo exista ele deve ser carregado, caso contrário um carregamento dos arquivos do *dataset* deve ser realizado, salvando os dados em uma arquivo `.npy` ao final. Essa função deve retornar um dicionário python contendo os dados de todos os voluntários.<jupyter_code># Sua função aqui<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0742580254391278, 'fraction_numerical': 0.016959418534221685, 'mean_word_length': 4.781512605042017, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 28, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '128655', 'license': 'CC0-1.0', 'n_tokens_mistral': 2912, 'n_tokens_neox': 2788, 'n_words': 1128, 'path': 'sEMG/01-load_dataset.ipynb', 'repo_name': 'bneurd/Tutoriais', 'size': '8280'}