Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exercicio Semana 11 - Pandas #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions exercicios/para-casa/ETL_JessicaBom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import pandas as pd

df = pd.read_csv("../../material/mais_ouvidas_2024.csv")

print(df.head())
print(df.dtypes)


#Aqui criamos uma variável que armazena em uma lista (nome_colunas) as colunas existentes em um csv, sem a necessidade de copiar e colar os valores
nome_colunas = df.columns.tolist()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qual a diferença do resultado entre um df.columns e um df.columns.tolist()?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu usei o df.columns.tolist() porque já armazenei na variável nome_colunas.
Fiz isso para aproveitar essa função do pandas, porque com isso não precisei digitar o nome de todas as colunas.

Copy link
Collaborator

@manuellysuzik manuellysuzik Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sim , compreendo. Mas o que quero dizer é que o to_list() e o .columns faz exatamente a mesma coisa. Ambos retornam uma Lista com o nome das colunas , porque optou por um ao invés do outro? 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Porque eu achei que o columns não fazia uma lista. Só o to_list. Mas faz sentido... não pensei que já estava OK com o columns.
Como eu ia pegar o resultado do columns, copiar e colar em uma variável, nem me toquei que, por si só, o resultado do columns já podia ser salvo em uma lista, haha.
(Shame, Shame, Shame)



#Para converter as colunas numéricas em formato de números não usei replace e astype. Usei direto o to_numeric e usei o replace para retirar as vírgulas em um for para fazer uma série de transformações. (1) analisa se a coluna é do tipo ocject, se sim (2) aplica o to_numeric, checando se aquele valor pode ser transformado em float ou int. Contudo, como haviam vírgulas em alguns números essa função não completava, por isso, apliquei o str.replace para trocar todas as vírgulas que ele encontrasse por vazio (""). Os erros foram ignorados, mas os espaços vazios foram substituídos por NaN. Preferi não filtrar com o fillna porque mudava o tipo da coluna como um todo para object quando havia um espaço vazio.
for coluna in nome_colunas:
if df[coluna].dtype == "object":
df[coluna] = pd.to_numeric(df[coluna].str.replace(",", ""), errors = "ignore")
Comment on lines +14 to +16
Copy link
Collaborator

@manuellysuzik manuellysuzik Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

essa parte tentar converter todas as colunas que tem o tipo object, isso inclui as colunas que DEVEM ser object e que não podem ser convertidas usando astype. Por isso usou to_numeric?

qual a diferença entre as duas funções?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quando fiz o código, achei mais prático usar o to_numeric, porque ele identifica meio que "automaticamente" o que pode ser numérico e já coloca como float ou como int pela própria função. Da primeira vez usei com o coerce e vi que ele transformava o que de fato tinha que ser object em NaN. Depois refiz utilizando o "ignore". Meu pensamento foi: se o to_numeric identifica o que é numérico e faz a conversão, eu faço um for passando por todas as coluna da variável "nome_colunas" e se aquilo não puder ser um número, o to_numeric vai ignorar com o "ignore" e aquilo permanece como string ou o outro formato.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Esse é uma ótima linha de pensamento!

Trago pra você outra análise então:

Se o ˋto_numericˋ detecta "automaticamente" se o valor pode ou não ser convertido, porquê os erros aconteceram? Quando tentamos converter com os astype se não for possível converter também recebemos erro. Em quê eles são diferentes?

Copy link
Author

@jessicabom jessicabom Aug 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essa pergunta aqui pegou professora. Fui olhar a documentação pra entender a diferença e depois recorri ao chatGPT porque não estava muito claro. Mas lá vai o que eu entendi.
Os erros usando o "to_numeric" aconteceram porque ele encontrou no DataFrame elementos que não podiam ser convertidos para números naquelas colunas que eu especifiquei.

Pelo que vi aqui, em tese não teria muita diferença o recebimento de erro dos dois, porque por padrão o retorno do "to_numeric" e do "astype" pra erros é o raise, ou seja, quando eles encontram um elemento que não pode ser convertido para o tipo desejado eles retornariam um erro imediato, um "ValueError"(acho).

Mas, assim como o "to_numeric", também podemos configurar o "as_type" para ignorar os erros. Pelo que vi na documentação ele tem por padrão errors=raise, mas também pode receber errors=ignore.
Provavelmente, nesse caso, o problema maior aqui é que o to_numeric pode converter os valores para NaN se configurarmos o errors=coerce, enquanto o astype não pode receber isso. Então - se for isso e se eu não embananei tudo - usar o astype para a conversão acaba sendo duplamente mais seguro. Seria isso?



#Convertendo a coluna Release Date para Datetime
df["Release Date"] = pd.to_datetime(df["Release Date"], errors = "ignore")


#Criando a coluna Streaming Popularity e calculando a média dos valores. A determinação do axis nesse caso é importante porque por padrão ele vem como None, e faz uma agregação em ambos os eixos, ou seja, exibiria o resultado geral em todas as linhas e como uma soma total da coluna. Determinando axis=1, estamos indicando que a operação vai ser realizada ao longo das linhas, individualmente.
df["Streaming Popularity"] = df[["Spotify Popularity", "YouTube Views", "TikTok Likes", "Shazam Counts"]].mean(axis=1)


#Criando a coluna Total Streams, com a mesma lógica utilizada acima.
df["Total Streams"] = df[["Spotify Streams", "YouTube Views", "TikTok Views", "Pandora Streams", "Soundcloud Streams"]].sum(axis=1)


#Prints de consulta criados para verificar os tipos das colunas após as conversões solicitadas.
print (df.dtypes)
print(df.head(20))


#Filtro aplicado para filtrar as faixas conforme solicitado no exercício. Adicionalmente foi criado um arquivo csv também
filtered_df = df[(df["Spotify Popularity"] > 80) & (df["Total Streams"] > 1000000)]
filtered_df.to_json("./filtered_list.json", index=False)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pq optou por usar index=False?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui eu copiei a mesma sintaxe que foi passada no "para-sala", mas lembrei que a professora disse que era pra não importar o número de índice do original, ou algo assim. Então mantive o index=False, como foi passado no para-sala.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isso mesmo! Kudos!

filtered_df.to_csv("./filtered_list.csv", index=False)


#Código para consultar o json criado
df = pd.read_json("./filtered_list.json")
print(df.head())
print(df.dtypes)


#Código para consultar o csv criado adicionalmente
df = pd.read_csv("./filtered_list.csv")
print(df.head())
print(df.dtypes)
14 changes: 7 additions & 7 deletions exercicios/para-casa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ O que preciso que faça:

Terminou o exercício? Dá uma olhada nessa checklist e confere se tá tudo certinho, combinado?!

- [ ] Fiz o fork do repositório.
- [ ] Clonei o fork na minha máquina (`git clone url-do-meu-fork`).
- [ ] Resolvi o exercício.
- [ ] Adicionei as mudanças. (`git add .` para adicionar todos os arquivos, ou `git add nome_do_arquivo` para adicionar um arquivo específico)
- [ ] Commitei a cada mudança significativa ou na finalização do exercício (`git commit -m "Mensagem do commit"`)
- [ ] Pushei os commits na minha branch (`git push origin nome-da-branch`)
- [ ] Criei um Pull Request seguindo as orientaçoes que estao nesse [documento](https://github.com/mflilian/repo-example/blob/main/exercicios/para-casa/instrucoes-pull-request.md).
- [] Fiz o fork do repositório.
- [] Clonei o fork na minha máquina (`git clone url-do-meu-fork`).
- [] Resolvi o exercício.
- [] Adicionei as mudanças. (`git add .` para adicionar todos os arquivos, ou `git add nome_do_arquivo` para adicionar um arquivo específico)
- [] Commitei a cada mudança significativa ou na finalização do exercício (`git commit -m "Mensagem do commit"`)
- [] Pushei os commits na minha branch (`git push origin nome-da-branch`)
- [] Criei um Pull Request seguindo as orientaçoes que estao nesse [documento](https://github.com/mflilian/repo-example/blob/main/exercicios/para-casa/instrucoes-pull-request.md).
Loading