Usando Pandas e Python para explorar seu conjunto de dados

Você tem um grande conjunto de dados cheio de insights interessantes, mas você não tem certeza por onde começar a explorá-lo? Seu chefe pediu para você gerar algumas estatísticas a partir dele, mas eles não são tão fáceis de extrair? Estes são precisamente os casos de uso onde Pandas e Python podem ajudá-lo! Com essas ferramentas, você será capaz de partir um grande conjunto de dados em partes gerenciáveis e obter insights dessas informações.

Neste tutorial, você aprenderá como:

  • Calcular métricas sobre seus dados
  • Realizar consultas básicas e agregações
  • Descubrir e manusear dados incorretos, inconsistências e valores perdidos
  • Visualizar seus dados com plots

Você também aprenderá sobre as diferenças entre as principais estruturas de dados que Pandas e Python usam. Para acompanhar, você pode obter todo o código de exemplo neste tutorial no link abaixo:

Há algumas coisas que você precisa começar com este tutorial. Primeiro é uma familiaridade com as estruturas de dados incorporadas do Python, especialmente listas e dicionários. Para obter mais informações, confira Listas e Tuplas em Python e Dicionários em Python.

A segunda coisa que você vai precisar é de um ambiente Python funcionando. Você pode acompanhar em qualquer terminal que tenha Python 3 instalado. Se você quiser ver uma saída mais agradável, especialmente para um grande conjunto de dados, então você pode querer executar projetos em um notebook Jupyter.

A última coisa que você vai precisar para iniciar, é da biblioteca Pandas Python, que você pode instalar com pip:

pip install pandas

Se você está usando a distribuição Anaconda, então você já está pronto para começar. A Anaconda já vem com a biblioteca Pandas Python instalada.

Se você vai usar python principalmente para o trabalho de ciência de dados, então talvez seja a melhor escolha. No ecossistema, você tem duas alternativas principais:

  1. Se você quer colocar um ambiente estável de ciência de dados em funcionamento rapidamente, e não se importar em baixar 500 MB de dados, então use a distribuição da Anaconda.
  2. Se você preferir uma configuração mais minimalista, então confira a seção sobre a instalação do Miniconda na configuração python para aprendizado de máquina no Windows.

Agora que você instalou pandas, é hora de dar uma olhada em um conjunto de dados. Neste tutorial, você analisará os resultados da NBA fornecidos pelo FiveThirtyEight em um arquivo CSV de 17MB .

import requestsdownload_url = "https://raw.githubusercontent.com/fivethirtyeight/data/master/nba-elo/nbaallelo.csv"target_csv_path = "nba_all_elo.csv"response = requests.get(download_url)response.raise_for_status()    # Checagem de statuswith open(target_csv_path, "wb") as f:
f.write(response.content)
print("Download ready.")

Quando você executar o script, ele salvará o arquivo em seu diretório de trabalho atual.

Nota: Você também pode usar seu navegador da Web para baixar o arquivo CSV.

No entanto, ter um script de download tem várias vantagens:

  • Você pode dizer onde você conseguiu seus dados.
  • Você pode repetir o download a qualquer hora! Isso é especialmente útil se os dados forem frequentemente atualizados.
  • Você não precisa compartilhar o arquivo CSV de 17MB com seus colegas de trabalho. Normalmente, é o suficiente para compartilhar o script de download.

Agora você pode usar a biblioteca Pandas Python para dar uma olhada em seus dados:

import pandas as pd
nba = pd.read_csv("nba_all_elo.csv")
type(nba)

Aqui, você segue a convenção de importar Pandas em Python com o pseudônimo. Em seguida, você usa para ler em seu conjunto de dados e armazená-lo como um objeto DataFrame na variável.

Nota: Seus dados não estão no formato CSV? Não se preocupe! A biblioteca Pandas Python fornece várias funções semelhantes. Para saber como trabalhar com esses formatos de arquivo, confira Lendo e Escrevendo Arquivos com Pandas ou consulte a documentação.

Você pode ver a quantidade de dados do DataFrame:

 len(nba)

nba.shape
126.314 registros e 23 atributos

Você usa a função incorporada python para determinar o número de linhas. Você também usa o atributo do para ver sua dimensionalidade. O resultado é uma tupla contendo o número de linhas e colunas.

Agora você sabe que há 126.314 linhas e 23 colunas em seu conjunto de dados. Mas como você pode ter certeza de que o conjunto de dados realmente contém estatísticas de basquete? Você pode dar uma olhada nas cinco primeiras linhas:

nba.head()

Se você está seguindo junto com um notebook Jupyter, então você verá um resultado como este:

A menos que sua tela seja bastante grande, sua saída provavelmente não exibirá todas as 23 colunas. Em algum lugar no meio, você verá uma coluna de elipses () indicando os dados faltantes.

Você pode configurar Pandas para exibir todas as 23 colunas:

 pd.set_option("display.max.columns", None)

Embora seja prático ver todas as colunas, você provavelmente não precisará de seis casas decimais:

pd.set_option("display.precision", 2)

Para verificar se você alterou as opções com sucesso, você pode executar novamente ou você pode exibir as últimas cinco linhas:

nba.tail()

Agora, você deve ver todas as colunas, e seus dados devem mostrar dois lugares decimais:

Semelhante à biblioteca padrão Python, as funções em Pandas também vêm com vários parâmetros opcionais. Sempre que você esbarrar em um exemplo que parece relevante, mas é ligeiramente diferente do seu caso de uso, confira a documentação oficial. As chances são boas de você encontrar uma solução ajustando alguns parâmetros opcionais!

Você importou um arquivo CSV com a biblioteca Pandas Python e deu uma primeira olhada no conteúdo do seu conjunto de dados. Até agora, você só viu o tamanho do seu conjunto de dados e suas primeiras e últimas linhas. Em seguida, você aprenderá como examinar seus dados de forma mais sistemática.

O primeiro passo para conhecer seus dados é descobrir os diferentes tipos de dados que ele contém. Embora você possa colocar qualquer coisa em uma lista, as colunas de um DataFrame contém tipos de dados específico.

Quando você compara estruturas de dados Pandas e Python, você verá que esse comportamento torna o Pandas muito mais rápido!

Você pode exibir todas as colunas e seus tipos de dados com:

nba.info()

Isso produzirá a seguinte saída:

Você verá uma lista de todas as colunas do seu conjunto de dados e o tipo de dados que cada coluna contém. Aqui, você pode ver os tipos de dados.

O tipo de dados ‘“object” é especial. De acordo com o Pandas Cookbook,o tipo de dados object muitas vezes significa que todos os valores da coluna são strings.

Agora que você viu quais tipos de dados estão em seu conjunto de dados, é hora de obter uma visão geral dos valores que cada coluna contém. Você pode fazer isso com:

nba.describe()

Esta função mostra algumas estatísticas básicas descritivas para todas as colunas numéricas:

.describe() apenas analisa colunas numéricas por padrão, mas você pode fornecer outros tipos de dados se você usar o parâmetro:

import numpy as np
nba.describe(include=np.object)

.describe() não tentará calcular uma média ou um desvio padrão para as colunas, uma vez que elas incluem principalmente strings de texto. No entanto, ele ainda exibirá algumas estatísticas descritivas para registros qualitativos

Dê uma olhada nas colunas. Seu conjunto de dados contém 104 IDs de equipe diferentes, mas apenas 53 diferentes IDs de franquia. Como isso é possível? Você precisará explorar seu conjunto de dados um pouco mais para responder a esta pergunta.

A análise exploratória de dados pode ajudá-lo a responder perguntas sobre seu conjunto de dados. Por exemplo, você pode examinar com que frequência valores específicos ocorrem em uma coluna:

nba["team_id"].value_counts()
nba["fran_id"].value_counts()

Parece que um time chamado jogou 6024 jogos, mas apenas 5078 deles foram jogados pelo Los Angeles Lakers. Descubra quem é a outra equipe:

nba.loc[nba["fran_id"] == "Lakers", "team_id"].value_counts()

De fato, o Minneapolis Lakers (em6 de brasília) jogou 946 jogos. Você pode até descobrir quando eles jogaram esses jogos:

nba.loc[nba["team_id"] == "MNL", "date_game"].min()
nba.loc[nba["team_id"] == "MNL", "date_game"].max()
nba.loc[nba["team_id"] == "MNL", "date_game"].agg(("min", "max"))

Parece que o Minneapolis Lakers jogou entre os anos de 1949 e 1959. Isso explica por que você pode não detectar esta equipe!

Você também descobriu por que o time do Boston Celtics jogou mais jogos. Vamos analisar um pouco a história deles. Descubra quantos pontos o Boston Celtics marcou durante todas as partidas contidas neste conjunto de dados.

Conhecendo as estruturas de dados da Pandas

Embora um forneça funções que podem parecer bastante intuitivas, os conceitos subjacentes são um pouco mais complicados de entender.

A estrutura de dados mais básica do Python é a lista, que também é um bom ponto de partida para conhecer:

revenues = pd.Series([5555, 7000, 1980])
revenues

Você usou a lista para criar um objeto chamado. Um objeto envolve dois componentes:

  1. Uma sequência de valores
  2. Uma sequência de identificadores, que é o índice

Você pode acessar esses componentes com:

revenues.values
revenues.index

revenues.values devolve os valores por cada índice da lista, enquanto Index retorna o índice posicional.

type(revenues.values)

Enquanto pandas se baseiam em NumPy, uma diferença significativa está em sua indexação. Assim como uma matriz NumPy, Pandas também tem um índice inteiro que é implicitamente definido. Este índice implícito indica a posição do elemento.

No entanto, um também pode ter um tipo arbitrário de índice. Você pode pensar neste índice explícito como rótulos para uma linha específica:

city_revenues = pd.Series(
[4200, 8000, 6500],
index = ["Amsterdam", "Toronto", "Tokyo"]
)
city_revenues

Aqui, o Índice é uma lista de nomes de cidades representados por cordas. Você deve ter notado que os dicionários Python também usam índices de string, e esta é uma analogia útil para ter em mente! Você pode usar os blocos de código acima para distinguir entre dois tipos de:

  1. revenues: Isso se comporta como uma lista Python porque tem apenas um índice posicional.
  2. city_revenues: Isso age como um dicionário Python porque possui pares de chave e valor.
city_employee_count = pd.Series({"Amsterdam": 5, "Tokyo": 8})
city_employee_count

As chaves do dicionário se tornam o índice, e os valores do dicionário são os valores.

city_employee_count.keys()"Tokyo" in city_employee_count"New York" in city_employee_count

Você pode usar esses métodos para responder perguntas sobre seu conjunto de dados rapidamente.

Entendendo objetos do DataFrame

Embora a seja uma estrutura de dados muito poderosa, ela tem suas limitações.

Por exemplo, você só pode armazenar um atributo por entrada. Como você já viu com o conjunto de dados, que possui 23 colunas, a biblioteca Pandas tem mais a oferecer com seu DataFrame. Esta estrutura de dados é uma sequência de objetos que compartilham o mesmo índice.

Se você acompanhou os exemplos, então você já deve ter dois objetos com cidades como chaves:

  1. city_revenues
  2. city_employee_count

Você pode combinar esses objetos em um fornecendo um dicionário no construtor. As chaves do dicionário se tornarão os nomes das colunas e os valores devem conter os objetos:

city_data = pd.DataFrame({
"revenue": city_revenues,
"employee_count": city_employee_count
})
city_data

Note como pandas substituiu o valor perdido para Toronto por NaN.

O novo índice é a união dos dois índices:

city_data.index

Assim como uma Series , um DataFrame também armazena seus valores em uma matriz NumPy:

city_data.values

Você também pode se referir às 2 dimensões de um DataFrame como eixos:

city_data.axes

city_data.axes[0]

city_data.axes[1]

O eixo marcado com 0 é o índice de linha,e o eixo marcado com 1 é o índice da coluna. Esta terminologia é importante saber porque você encontrará vários métodos que aceitam um parâmetro.DataFrameaxis

O DataFrame também é uma estrutura de dados semelhante a um dicionário, por isso também suporta e a palavra-chave. No entanto, para um DataFrame estes não se relacionam com o índice, mas com ascolunas:

city_data.keys()"Amsterdam" in city_data

"revenue" in city_data

Você pode ver esses conceitos em ação com o maior conjunto de dados da NBA. Contém uma coluna chamada ‘points’, ou foi chamada de ‘pts’? Para responder a esta pergunta, exiba o índice e os eixos do conjunto de dados NBA e expanda o bloco de código abaixo para a solução:

Como você não especificou uma coluna de índice quando leu no arquivo CSV, pandas atribuiu um Index ao DataFrame:

nba.index

nba, como todos os objetos, tem dois eixos:DataFrame

nba.axes

Você pode verificar a existência de uma coluna com:.keys()

"points" in nba.keys()"pts" in nba.keys()

A coluna é chamada “pts”, não “points”.

Ao usar esses métodos para responder perguntas sobre seu conjunto de dados, não deixe de ter em mente se você está trabalhando com uma Series ou um DataFrame para que sua interpretação seja precisa.

Acessando elementos da série

Na seção acima, você criou um Pandas baseado em uma lista Python e comparou as duas estruturas de dados. Você viu como um objeto é semelhante a listas e dicionários de várias maneiras. Uma outra semelhança é que você pode usar o operador de indexação () também.

Você também aprenderá a usar dois métodos de acesso específicos do Pandas:

  1. .loc
  2. .iloc

Você verá que esses métodos de acesso a dados podem ser muito mais legíveis do que o operador de indexação.

Utilizando o Operador de Indexação

Lembre-se que um tem dois índices:Series

  1. Um índice posicional ou implícito,que é sempre um RangeIndex
  2. Um rótulo ou índice explícito, que pode conter quaisquer objetos hash

Em seguida, revisite o objeto:city_revenues

city_revenues

Você pode acessar convenientemente os valores de uma Series um com os índices de rótulo ou posicionais:

city_revenues["Toronto"]city_revenues[1]

Você também pode usar índices e fatias negativas, assim como faria com uma lista:

city_revenues[-1]city_revenues[1:]

city_revenues["Toronto":]

O operador de indexação é conveniente, mas há uma ressalva. E se os rótulos também forem números? Digamos que você tem que trabalhar com um objeto como este:

colors = pd.Series(
["red", "purple", "blue", "green", "yellow"],
index = [1, 2, 3, 5, 8]
)
colors
  1. .loc refere-se ao índice de rótulos.
  2. .iloc refere-se ao índice posicional.

Esses métodos de acesso a dados são muito mais legíveis:

colors.loc[1]

colors.iloc[1]

Se você pensa em um DataFrame como um icionário cujos valores são Series, então faz sentido que você possa acessar suas colunas com o operador de indexação:

city_data["revenue"]

type(city_data["revenue"])

Aqui, você usa o operador de indexação para selecionar a coluna rotulada como "revenue"

Se o nome da coluna for uma string, então você pode usar o acesso ao atributo com outra notação, usando ponto.

city_data.revenue
Retornam a mesma saída

Há uma situação em que acessar elementos com notação de pontos pode não funcionar ou pode levar a surpresas. É quando um nome de coluna coincide com um atributo ou nome do método:

toys = pd.DataFrame([
{"name": "ball", "shape": "sphere"},
{"name": "Rubik's cube", "shape": "cube"}
])

toys["shape"]
toys.shape

Semelhante a uma Serie, um DataFrametambém fornece e métodos de acesso a dados. Lembre-se, usa o rótulo e o índice posicional:

city_data.loc["Amsterdam"]

city_data.loc["Tokyo": "Toronto"]

city_data.iloc[1]

Cada linha de código seleciona uma linha diferente de:city_data

  1. city_data.loc["Amsterdam"] seleciona a linha com o índice de rótulos ."Amsterdam"
  2. city_data.loc["Tokyo": "Toronto"] seleciona as linhas com índices de rótulos de . Lembre-se, é inclusivo."Tokyo""Toronto".loc
  3. city_data.iloc[1] seleciona a linha com o índice posicional, que é .1"Tokyo"

Enquanto o primeiro parâmetro seleciona linhas com base nos índices, o segundo parâmetro seleciona as colunas. Você pode usar esses parâmetros juntos para selecionar um subconjunto de linhas e colunas do seu DataFrame:

city_data.loc["Amsterdam": "Tokyo", "revenue"]

Consultando seu conjunto de dados

Você viu como acessar subconjuntos de um enorme conjunto de dados com base em seus índices. Agora, você selecionará linhas com base nos valores nas colunas do seu conjunto de dados para consultar seus dados.

Por exemplo, você pode criar um novo DataFrame que contém apenas jogos jogados após 2010:

current_decade = nba[nba["year_id"] > 2010]current_decade.shape

Você ainda tem todas as 23 colunas, mas a sua nova coluna consiste apenas em linhas onde o valor na coluna é maior do que o especificado.

Você também pode selecionar as linhas onde um campo específico não é nulo:

games_with_notes = nba[nba["notes"].notnull()]games_with_notes.shape

Isso pode ser útil se você quiser evitar qualquer valor faltando em uma coluna.

Você usa para filtrar seu conjunto de dados e encontrar todos os jogos onde o nome do time da casa termina com:

ers = nba[nba["fran_id"].str.endswith("ers")]ers.shape

Faça uma busca por jogos em Baltimore onde ambas as equipes marcaram mais de 100 pontos. Para ver cada jogo apenas uma vez, você precisará excluir duplicatas:

nba[
(nba["_iscopy"] == 0) &
(nba["pts"] > 100) &
(nba["opp_pts"] > 100) &
(nba["team_id"] == "BLB")
]

Sua saída deve conter cinco jogos agitados:

Agrupando e agregando seus dados

Você também pode querer aprender outras características do seu conjunto de dados, como a soma, média ou valor médio de um grupo de elementos. Felizmente, a biblioteca Pandas Python oferece funções de agrupamento e agregação para ajudá-lo a realizar essa tarefa.

A tem mais de vinte métodos diferentes para calcular estatísticas descritivas.

city_revenues.sum()

city_revenues.max()

O primeiro método retorna o total de city_revenues , enquanto o segundo retorna o valor máximo. Existem outros métodos que você pode usar, como:city_revenues.min().mean()

Lembre-se, uma coluna de um DataFrame é na verdade um objeto. Por essa razão, você pode usar essas mesmas funções nas colunas das Series:

points = nba["pts"]type(points)points.sum()

O DataFrame pode ter várias colunas, o que introduz novas possibilidades de agregações, como agrupamento:

nba.groupby("fran_id", sort = False)["pts"].sum()

Por padrão, Pandas classifica as chaves do grupo durante a chamada de groupby() . Se você não quer classificar, então passar o parâmetro sort False. Este parâmetro pode levar a ganhos de desempenho.

Você também pode agrupar por várias colunas:

nba[
(nba["fran_id"] == "Spurs") &
(nba["year_id"] > 2010)
].groupby(["year_id", "game_result"])["game_id"].count()

Você precisará saber como manipular as colunas do seu conjunto de dados em diferentes fases do processo de análise de dados. Você pode adicionar e dropar colunas como parte da fase inicial de limpeza de dados, ou mais tarde com base nos insights de sua análise.

Crie uma cópia do seu original para trabalhar:

df = nba.copy()
df.shape

Você pode definir novas colunas com base nas já existentes:

 df["difference"] = df.pts - df.opp_pts
df.shape

Aqui, você usou as colunas para criar uma nova chamada . Esta nova coluna tem as mesmas funções das antigas:

df["difference"].max()

Aqui, você usou uma função de agregação para encontrar o maior valor da sua nova coluna.

Você também pode renomear as colunas do seu conjunto de dados. Parece que e são muito verbosos, então vá em frente e renomeie-os agora:

renamed_df = df.rename(
columns = {"game_result": "result", "game_location": "location"}
)
renamed_df.info()

Ao criarum novo DataFrame chamando um construtor ou lendo um arquivo CSV, o Pandas atribui um tipo de dados a cada coluna com base em seus valores. Embora faça um bom trabalho, não é perfeito.

Se você escolher o tipo de dados certo para suas colunas antecipadamente, então você pode melhorar significativamente o desempenho do código:

df.info()

Você verá a mesma saída de antes:

Dez de suas colunas têm o tipo de dados. A maioria dessas colunas contém texto arbitrário object:

df["date_game"] = pd.to_datetime(df["date_game"])

Outras colunas contêm texto um pouco mais estruturado. A coluna pode ter apenas três valores diferentes:

df["game_location"].nunique()
3
df["game_location"].value_counts()
A 63138
H 63138
N 38

Qual tipo de dados você usaria em um banco de dados relacional para tal coluna? Você provavelmente não usaria um tipo varchar, mas sim um caterigocal. Pandas fornece o tipo de dados para o mesmo propósito:

df["game_location"] = pd.Categorical(df["game_location"])df["game_location"].dtypeCategoricalDtype(categories=['A', 'H', 'N'], ordered=False)

dados categóricos têm algumas vantagens sobre texto não estruturado. Quando você especifica o tipo de dados, facilita a validação e salva uma tonelada de memória, pois o Pandas usará apenas os valores únicos internamente. Quanto maior a proporção de valores totais para valores únicos, mais economias de espaço você terá.categorical

Nota: O tipo de dados também lhe dá acesso a métodos adicionais através do acessório. Para saber mais, confira os documentos oficiais.categorical.cat

Muitas vezes você encontrará conjuntos de dados com muitas colunas de texto. Uma habilidade essencial para os cientistas de dados terem é a capacidade de identificar quais colunas eles podem converter para um tipo de dados mais performático.

Você já se perguntou por que mostra quantos valores não nulos uma coluna contém? A razão é que esta é uma informação vital. Valores nulos muitas vezes indicam um problema no processo de coleta de dados. Eles podem fazer várias técnicas de análise, como diferentes tipos de aprendizado de máquina, difíceis ou até mesmo impossíveis.

Quando você inspecionar o conjunto de dados com .info(), você verá que é bastante limpo. Apenas a coluna contém valores nulos para a maioria de suas linhas:

Esta saída mostra que a coluna tem apenas 5424 valores não nulos. Isso significa que mais de 120.000 linhas do seu conjunto de dados têm valores nulos nesta coluna.

Às vezes, a maneira mais fácil de lidar com registros que contêm valores perdidos é ignorá-los. Você pode remover todas as linhas com valores faltantes usando.dropna()

rows_without_missing_data = nba.dropna()rows_without_missing_data.shape

Claro, esse tipo de limpeza de dados não faz sentido para o seu conjunto de dados, porque não é um problema para um jogo não ter notas. Mas se o seu conjunto de dados contém um milhão de registros válidos e cem onde faltam dados relevantes, então deixar cair os registros incompletos pode ser uma solução razoável.

Você também pode soltar colunas problemáticas se elas não forem relevantes para sua análise. Para isso, use novamente e forneça o parâmetro:

data_without_missing_columns = nba.dropna(axis=1)data_without_missing_columns.shape

Se houver um valor padrão significativo para o seu caso de uso, então você também pode substituir os valores faltantes por isso:

data_with_default_notes = nba.copy()data_with_default_notes["notes"].fillna(
value="no notes at all",
inplace=True
)
data_with_default_notes["notes"].describe()

Valores inválidos podem ser ainda mais perigosos do que valores perdidos. Muitas vezes, você pode realizar sua análise de dados como esperado, mas os resultados que você recebe são peculiares. Isso é especialmente importante se o seu conjunto de dados for enorme ou usado de entrada manual. Valores inválidos são muitas vezes mais desafiadores de detectar, mas você pode implementar algumas verificações de sanidade com consultas e agregações.

Uma coisa que você pode fazer é validar os intervalos de seus dados. Para isso, é muito útil. Lembre-se de que retorna a seguinte saída:describe()

nba[nba["pts"] == 0]

Esta consulta retorna uma única linha:

Parece que o jogo foi perdido. Dependendo da sua análise, você pode querer removê-lo do conjunto de dados.

Na seção anterior, você aprendeu a limpar um conjunto de dados bagunçado. Outro aspecto dos dados do mundo real é que muitas vezes vem em várias partes. Nesta seção, você aprenderá a pegar essas peças e combiná-las em um conjunto de dados pronto para análise.

Antes,você combinou dois objetos em um baseado em seus índices. Agora, você vai dar um passo adiante e usar para combinar com outro DataFrame. Digamos que você conseguiu reunir alguns dados sobre mais duas cidades:

further_city_data = pd.DataFrame(
{"revenue": [7000, 3400], "employee_count":[2, 2]},
index=["New York", "Barcelona"]
)
all_city_data = pd.concat(
[city_data, further_city_data],
sort=False)
all_city_data
Amsterdam 4200 5.0
Tokyo 6500 8.0
Toronto 8000 NaN
New York 7000 2.0
Barcelona 3400 2.0

Por padrão, combina com concat(). Em outras palavras, ele anexa em linhas. Você também pode usá-lo para anexar colunas ajustando o parâmetro axis:

city_countries = pd.DataFrame({
"country": ["Holland", "Japan", "Holland", "Canada", "Spain"],
"capital": [1, 1, 0, 0, 0]},
index=["Amsterdam", "Tokyo", "Rotterdam", "Toronto", "Barcelona"]
)
cities = pd.concat([all_city_data, city_countries], axis=1, sort=False)cities
revenue employee_count country capital
Amsterdam 4200.0 5.0 Holland 1.0
Tokyo 6500.0 8.0 Japan 1.0
Toronto 8000.0 NaN Canada 0.0
New York 7000.0 2.0 NaN NaN
Barcelona 3400.0 2.0 Spain 0.0
Rotterdam NaN NaN Holland 0.0

Note como pandas adicionados para os valores faltantes NaN. Se você quiser combinar apenas as cidades que aparecem em ambos os objetos, então você pode definir o parâmetro para join = inner

pd.concat([all_city_data, city_countries], axis=1, join="inner")
revenue employee_count country capital
Amsterdam 4200 5.0 Holland 1
Tokyo 6500 8.0 Japan 1
Toronto 8000 NaN Canada 0
Barcelona 3400 2.0 Spain 0

Embora seja mais simples combinar dados com base no índice, não é a única possibilidade. Você pode usar .merge() para implementar uma operação de join semelhante à do SQL:

countries = pd.DataFrame({
"population_millions": [17, 127, 37],
"continent": ["Europe", "Asia", "North America"]
}, index= ["Holland", "Japan", "Canada"])
pd.merge(cities, countries, left_on="country", right_index=True)

Aqui, você passa o parâmetro para indicar em que coluna você deseja participar. O resultado é maior que contém não apenas dados da cidade, mas também a população e o continente dos respectivos países:left_on="country".merge()DataFrame

Note que o resultado contém apenas as cidades onde o país é conhecido e aparece no aderido.DataFrame

.merge() realiza uma junta interna por padrão. Se você quiser incluir todas as cidades no resultado, então você precisa fornecer o parâmetro:how

 pd.merge(
cities,
countries,
left_on="country",
right_index=True,
how="left"
)

Com esta adesão, você verá todas as cidades, incluindo aquelas sem dados do país:left

Bem-vindos de volta, Nova York e Barcelona!

Visualizando seu DataFrame pandas

Visualização de dados é uma das coisas que funciona muito melhor em um notebook Jupyter do que em um terminal, então vá em frente e dispare um para cima. Se você precisa de ajuda para começar, então confira Jupyter Notebook: An Introduction. Você também pode acessar o notebook Jupyter que contém os exemplos deste tutorial clicando no link abaixo:

Obtenha O Caderno Jupyter: Clique aqui para obter o Caderno Jupyter que você usará para explorar dados com Pandas neste tutorial.

Inclua esta linha para mostrar os enredos diretamente no caderno:

%matplotlib inline

Ambos e objetos têm um método .plot(), que é um invólucro ao redor . Por padrão, ele cria um gráfico de linha. Visualize quantos pontos os Knicks marcaram ao longo das temporadas:

nba[nba["fran_id"] == "Knicks"].groupby("year_id")["pts"].sum().plot()

Isso mostra um enredo de linha com vários picos e dois vales notáveis ao redor dos anos 2000 e 2010:

Você também pode criar outros tipos de parcelas, como um enredo de barra:

nba["fran_id"].value_counts().head(10).plot(kind="bar")

Isso mostrará as franquias com mais jogos jogados:

Os Lakers estão liderando os Celtics por uma vantagem mínima, e há mais seis equipes com uma contagem de jogos acima de 5000.

Agora tente um exercício mais complicado. Em 2013, o Miami Heat venceu o campeonato. Crie um enredo de torta mostrando a contagem de suas vitórias e perdas durante essa temporada. Em seguida, expanda o bloco de código para ver uma solução:

Às vezes, os números falam por si mesmos, mas muitas vezes um gráfico ajuda muito na comunicação de seus insights.

Obrigado

Composing a repository of books (i bought), authors (i follow) & blogs (direct ones) for my own understanding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store