Pandas

Funções Importantes

Importando o Pandas e o NumPy


In [1]:
import numpy as np
import pandas as pd

Reindexação


In [2]:
obj = pd.Series([4.5,7.2,-5.3,3.6], index=['d','b','a','c'])
obj


Out[2]:
d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64

Series reorganizam os dados de acordo com o novo índice, introduzindo um valor vazio no caso de algum valor ausente.


In [3]:
obj2 = obj.reindex(['a','b','c','d','e'])
obj2


Out[3]:
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

In [4]:
obj.reindex(['a','b','c','d','e'], fill_value=0)


Out[4]:
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64

Com um DataFrame, o método reindex pode alterar o index (linhas) as colunas ou ambos. Quando passado apenas uma sequência, as linhas são reindexadas


In [5]:
frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
frame


Out[5]:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8

In [6]:
frame2 = frame.reindex(['a','b','c','d'])
frame2


Out[6]:
Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0

As colunas podem ser reindexadas utilizando o parâmetro columns


In [7]:
states = ['Texas', 'Utah', 'California']

frame.reindex(columns=states)


Out[7]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8

Ambos podem ser reindexados de uma só vez


In [8]:
frame.reindex(index=['a','b','c','d'], columns=states)


Out[8]:
Texas Utah California
a 1.0 NaN 2.0
b NaN NaN NaN
c 4.0 NaN 5.0
d 7.0 NaN 8.0

Deletando entradas de um eixo


In [9]:
obj = pd.Series(np.arange(5.), index=['a','b','c','d','e'])
obj


Out[9]:
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

In [10]:
obj.drop('c')


Out[10]:
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

In [11]:
obj.drop(['d','c'])


Out[11]:
a    0.0
b    1.0
e    4.0
dtype: float64

Com DataFrame, os valores de índice podem ser deletados de ambos os eixos


In [12]:
data = pd.DataFrame(np.arange(16).reshape((4, 4)), \
                    index=['Ohio', 'Colorado', 'Utah', 'New York'], \
                    columns=['one', 'two', 'three', 'four'])

data


Out[12]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

In [13]:
data.drop(['Colorado', 'Ohio'])


Out[13]:
one two three four
Utah 8 9 10 11
New York 12 13 14 15

In [14]:
data.drop('two', axis=1)


Out[14]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15

In [15]:
data.drop(['two','four'], axis=1)


Out[15]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14

Indexando, selecioando e filtrando


In [16]:
obj = pd.Series(np.arange(4.), index=['a','b','c','d'])
obj


Out[16]:
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64

Segue alguns exemplos de formas de acessar os elemento em uma Series


In [17]:
# pelo nome do índice

obj['b']


Out[17]:
1.0

In [18]:
# pela posição no vetor de valores

obj[1]


Out[18]:
1.0

In [19]:
# por um intervalo

obj[2:4]


Out[19]:
c    2.0
d    3.0
dtype: float64

In [20]:
# através de uma lista de nomes

obj[['b','a','d']]


Out[20]:
b    1.0
a    0.0
d    3.0
dtype: float64

In [21]:
# através de uma lista de posições

obj[[1,3]]


Out[21]:
b    1.0
d    3.0
dtype: float64

In [22]:
# através de uma operação booleana

obj[obj < 2]


Out[22]:
a    0.0
b    1.0
dtype: float64

Ao fazer essa indexação em um DataFrame recuperamos uma ou mais colunas.


In [23]:
data = pd.DataFrame(np.arange(16).reshape((4, 4)), \
                    index=['Ohio', 'Colorado', 'Utah', 'New York'], \
                    columns=['one', 'two', 'three', 'four'])

data


Out[23]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

Segue algumas formas de acessar e modificar os elementos de um DataFrame


In [24]:
data['two']


Out[24]:
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int64

In [25]:
data[['three','one']]


Out[25]:
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12

In [26]:
data[:2]


Out[26]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7

In [27]:
data[data['three'] > 5]


Out[27]:
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

In [28]:
data < 5


Out[28]:
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False

In [29]:
data[data < 5] = 0
data


Out[29]:
one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

Na seguinte tabela é possível ver outras madeiras de fazer essas operações de indexação

Type Notes
obj[val] Select single column or sequence of columns from the DataFrame. Special case conveniences: boolean array (filter rows), slice (slice rows), or boolean DataFrame (set values based on some criterion).
obj.ix[val] Selects single row of subset of rows from the DataFrame.
obj.ix[:, val] Selects single column of subset of columns.
obj.ix[val1, val2] Select both rows and columns.
reindex method Conform one or more axes to new indexes.
xs method Select single row or column as a Series by label.
icol, irow methods Select single column or row, respectively, as a Series by integer location.
get_value, set_value methods Select single value by row and column label.

Aritimética e alinhamento de dados


In [30]:
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])

In [31]:
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'])

In [32]:
s1


Out[32]:
a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64

In [33]:
s2


Out[33]:
a   -2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64

Quando uma das Series não possui valor em um índice, no resultado é atribuído um resultado vazio naquele índice.


In [34]:
s1 + s2


Out[34]:
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64

No caso dos DataFrame, o alinhamento é feito nas linhas e colunas ao mesmo tempo.


In [35]:
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'])
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [36]:
df1


Out[36]:
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0

In [37]:
df2


Out[37]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

In [38]:
df1 + df2


Out[38]:
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN

Para evitar que esses valores vazios sejam atribuídos é possível subtituir um valor não existente em uma das Series ou DataFrames por um certo valor padrão.


In [39]:
df1.add(df2, fill_value=0)


Out[39]:
b c d e
Colorado 6.0 7.0 8.0 NaN
Ohio 3.0 1.0 6.0 5.0
Oregon 9.0 NaN 10.0 11.0
Texas 9.0 4.0 12.0 8.0
Utah 0.0 NaN 1.0 2.0

Também é possível fazer operações aritméticas entre DataFrames e Series.


In [40]:
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [41]:
series = frame.ix[0]

In [42]:
frame


Out[42]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

In [43]:
series


Out[43]:
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64

In [44]:
frame - series


Out[44]:
b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0

Se um valor não for encontrado nas colunas do DataFrame ou no índice da Series, o resultado vai ser reindexado para formar a união dos dois


In [45]:
series2 = pd.Series(range(3), index=['b', 'e', 'f'])

frame + series2


Out[45]:
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN

Se você quer realizar a operação com a Series pelas colunas ao invés de pelas linhas é necessário utilizar um dos métodos aritméticos


In [46]:
series3 = frame['d']

frame.sub(series3, axis=0)


Out[46]:
b d e
Utah -1.0 0.0 1.0
Ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
Oregon -1.0 0.0 1.0

Aplicação de funções e mapeamento

As funções de vetor do numpy funcionam bem com objetos do pandas


In [47]:
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame


Out[47]:
b d e
Utah 1.330722 0.561547 -0.865395
Ohio -0.051651 -0.975292 -0.005929
Texas 0.488482 0.831162 -0.748690
Oregon -0.763333 1.268824 -1.620376

In [48]:
np.abs(frame)


Out[48]:
b d e
Utah 1.330722 0.561547 0.865395
Ohio 0.051651 0.975292 0.005929
Texas 0.488482 0.831162 0.748690
Oregon 0.763333 1.268824 1.620376

Outra operação frequente é aplicar uma função de um vetor unidimensional para cada coluna ou linha do DataFrame. O método apply faz exatamente isso.


In [49]:
f = lambda x: x.max() - x.min()

In [50]:
frame.apply(f)


Out[50]:
b    2.094056
d    2.244116
e    1.614447
dtype: float64

In [51]:
frame.apply(f, axis=1)


Out[51]:
Utah      2.196117
Ohio      0.969363
Texas     1.579852
Oregon    2.889200
dtype: float64

Também é possível usar funções sobre elementos (ao invés de sobre vetores). Para isso você pode usar applymap quando estiver usando um DataFrame ou map quando estiver usando uma Series


In [52]:
format = lambda x: '%.2f' % x

In [53]:
frame.applymap(format)


Out[53]:
b d e
Utah 1.33 0.56 -0.87
Ohio -0.05 -0.98 -0.01
Texas 0.49 0.83 -0.75
Oregon -0.76 1.27 -1.62

In [54]:
frame['e'].map(format)


Out[54]:
Utah      -0.87
Ohio      -0.01
Texas     -0.75
Oregon    -1.62
Name: e, dtype: object