3 Métodos de como Alterar tipo da coluna com pandas

3 Métodos de como Alterar tipo da coluna com pandas

Compartilhe!

3 Métodos de como Alterar tipo da coluna com pandas

Dúvida:

Criei um DataFrame a partir de uma lista de listas:

table = [
    ['a',  '1.2',  '4.2' ],
    ['b',  '70',   '0.03'],
    ['x',  '5',    '0'   ],
]

df = pd.DataFrame(table)

Como converto as colunas em tipos específicos? Nesse caso, quero converter as colunas 2 e 3 em tipo float.

Existe uma maneira de especificar os tipos durante a conversão para DataFrame? Ou é melhor criar o DataFrame primeiro e depois percorrer as colunas para alterar o tipo de cada coluna? Idealmente, gostaria de fazer isso de maneira dinâmica, porque pode haver centenas de colunas e não quero especificar exatamente quais colunas são de que tipo. Tudo o que posso garantir é que cada coluna contém valores do mesmo tipo.

Método 1

Você tem quatro opções principais para converter tipos em pandas:

  1. to_numeric() – fornece funcionalidade para converter com segurança tipos não numéricos ( por exemplo strings ) para um tipo numérico adequado. ( Veja também to_datetime() e to_timedelta().)
  2. astype() – converter ( quase ) qualquer tipo para ( quase ) qualquer outro tipo (, mesmo que não seja necessariamente sensato fazê-lo ). Também permite converter para categorial tipos ( muito úteis ).
  3. infer_objects()– um método utilitário para converter colunas de objetos mantendo objetos Python em um tipo de pandas, se possível.
  4. convert_dtypes() – converta as colunas DataFrame no dtype “melhor possível” que suporta pd.NA ( objeto de pandas para indicar um valor ausente ).

Continue lendo para obter explicações e uso mais detalhados de cada um desses métodos.


1. to_numeric()

A melhor maneira de converter uma ou mais colunas de um DataFrame em valores numéricos é usar pandas.to_numeric().

Esta função tentará alterar objetos não numéricos (, como cadeias ), em números inteiros ou de ponto flutuante, conforme apropriado.

Uso básico

A entrada para to_numeric() é uma série ou uma única coluna de um DataFrame.

>>> s = pd.Series(["8", 6, "7.5", 3, "0.9"]) # mixed string and numeric values
>>> s
0      8
1      6
2    7.5
3      3
4    0.9
dtype: object

>>> pd.to_numeric(s) # convert everything to float values
0    8.0
1    6.0
2    7.5
3    3.0
4    0.9
dtype: float64

Como você pode ver, uma nova série é retornada. Lembre-se de atribuir essa saída a uma variável ou nome de coluna para continuar usando-a:

# convert Series
my_series = pd.to_numeric(my_series)

# convert column "a" of a DataFrame
df["a"] = pd.to_numeric(df["a"])

Você também pode usá-lo para converter várias colunas de um DataFrame através do apply() método:

# convert all columns of DataFrame
df = df.apply(pd.to_numeric) # convert all columns of DataFrame

# convert just columns "a" and "b"
df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)

Contanto que todos os seus valores possam ser convertidos, provavelmente é tudo o que você precisa.

Tratamento de erros

Mas e se alguns valores não puderem ser convertidos para um tipo numérico?

to_numeric() também leva um errors argumento de palavra-chave que permite forçar valores não numéricos a serem NaN, ou simplesmente ignore colunas contendo esses valores.

Aqui está um exemplo usando uma série de strings s que possui o objeto dtype:

>>> s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
>>> s
0         1
1         2
2       4.7
3    pandas
4        10
dtype: object

O comportamento padrão é aumentar se não puder converter um valor. Nesse caso, ele não pode lidar com a corda ‘pandas’:

>>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise')
ValueError: Unable to parse string

Em vez de falhar, podemos querer que ‘pandas’ sejam considerados um valor numérico ausente / ruim. Podemos coagir valores inválidos para NaN da seguinte maneira usando o errors argumento da palavra-chave:

>>> pd.to_numeric(s, errors='coerce')
0     1.0
1     2.0
2     4.7
3     NaN
4    10.0
dtype: float64

A terceira opção para errors é apenas para ignorar a operação se um valor inválido for encontrado:

>>> pd.to_numeric(s, errors='ignore')
# the original Series is returned untouched

Esta última opção é particularmente útil para converter todo o DataFrame, mas não sei qual das nossas colunas pode ser convertida de maneira confiável para um tipo numérico. Nesse caso, basta escrever:

df.apply(pd.to_numeric, errors='ignore')

A função será aplicada a cada coluna do DataFrame. As colunas que podem ser convertidas para um tipo numérico serão convertidas, enquanto as colunas que não podem ( por exemplo elas contêm cadeias ou datas não dígitos ) serão deixadas em paz.

Downcasting

Por padrão, conversão com to_numeric() lhe dará um int64 ou float64 dtype ( ou qualquer largura inteira que seja nativa da sua plataforma ).

Geralmente é o que você deseja, mas e se você quiser economizar um pouco de memória e usar um dtype mais compacto, como float32, ou int8?

to_numeric() oferece a opção de reduzir para 'integer''signed''unsigned''float'. Aqui está um exemplo para uma série simples s do tipo inteiro:

>>> s = pd.Series([1, 2, -7])
>>> s
0    1
1    2
2   -7
dtype: int64

Downcasting to 'integer' usa o menor número inteiro possível que pode conter os valores:

>>> pd.to_numeric(s, downcast='integer')
0    1
1    2
2   -7
dtype: int8

Downcasting to 'float' escolhe da mesma forma um tipo flutuante menor que o normal:

>>> pd.to_numeric(s, downcast='float')
0    1.0
1    2.0
2   -7.0
dtype: float32

2). astype()

astype() O método permite que você seja explícito sobre o dtype que deseja que seu DataFrame ou Série tenha. É muito versátil, pois você pode tentar passar de um tipo para outro.

Uso básico

Basta escolher um tipo: você pode usar um tipo de NumPy ( por exemplo. np.int16), alguns tipos de Python ( por exemplo bool ) ou tipos específicos de pandas (, como o dtype categórico ).

Chame o método no objeto que você deseja converter e astype() tentará convertê-lo para você:

# convert all DataFrame columns to the int64 dtype
df = df.astype(int)

# convert column "a" to int64 dtype and "b" to complex type
df = df.astype({"a": int, "b": complex})

# convert Series to float16 type
s = s.astype(np.float16)

# convert Series to Python strings
s = s.astype(str)

# convert Series to categorical type - see docs for more details
s = s.astype('category')

Observe que eu disse “try” – se astype() não sabe como converter um valor no Series ou DataFrame, ele gerará um erro. Por exemplo, se você tiver um NaN ou inf valor, você receberá um erro ao tentar convertê-lo em um número inteiro.

A partir dos pandas 0.20.0, esse erro pode ser suprimido passando errors='ignore'. Seu objeto original será devolvido intocado.

Tenha cuidado

astype()é poderoso, mas às vezes converte valores “incorretamente”. Por exemplo:

>>> s = pd.Series([1, 2, -7])
>>> s
0    1
1    2
2   -7
dtype: int64

Esses são números inteiros pequenos, então que tal converter para um tipo de 8 bits não assinado para salvar memória?

>>> s.astype(np.uint8)
0      1
1      2
2    249
dtype: uint8

A conversão funcionou, mas o -7 foi encerrado para se tornar 249 ( i.e. 28 – 7 )!

Tentando reduzir o tamanho usando pd.to_numeric(s, downcast='unsigned') em vez disso, poderia ajudar a evitar esse erro.


3). infer_objects()

A versão 0.21.0 dos pandas introduziu o método infer_objects() para converter colunas de um DataFrame que possuem um tipo de dados de objeto para um tipo mais específico ( conversões de software ).

Por exemplo, aqui está um DataFrame com duas colunas do tipo de objeto. Um contém números inteiros reais e o outro contém cadeias representando números inteiros:

>>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
>>> df.dtypes
a    object
b    object
dtype: object

Usando infer_objects(), você pode alterar o tipo de coluna ‘a’ para int64:

>>> df = df.infer_objects()
>>> df.dtypes
a     int64
b    object
dtype: object

A coluna ‘b’ foi deixada sozinha, pois seus valores eram cadeias, não números inteiros. Se você deseja forçar as duas colunas a um tipo inteiro, pode usar df.astype(int) em vez disso.


4). convert_dtypes()

A versão 1.0 e acima inclui um método convert_dtypes() converter colunas Series e DataFrame para o melhor dtype possível que suporte pd.NA valor ausente.

Aqui “melhor possível” significa o tipo mais adequado para manter os valores. Por exemplo, esse é um tipo inteiro de pandas, se todos os valores forem números inteiros ( ou valores ausentes ): uma coluna de objeto dos objetos inteiros do Python será convertida em Int64, uma coluna de NumPy int32 valores, se tornará o pandas dtype Int32.

Com a nossa object DataFrame df, obtemos o seguinte resultado:

>>> df.convert_dtypes().dtypes                                             
a     Int64
b    string
dtype: object

Como a coluna ‘a’ mantinha valores inteiros, ela foi convertida para o Int64 tipo ( capaz de manter valores ausentes, ao contrário int64).

A coluna ‘b’ continha objetos de string, então foi alterada para pandas’ string dtype.

Por padrão, esse método inferirá o tipo dos valores do objeto em cada coluna. Podemos mudar isso passando infer_objects=False:

>>> df.convert_dtypes(infer_objects=False).dtypes                          
a    object
b    string
dtype: object

Agora a coluna ‘a’ permaneceu uma coluna de objeto: os pandas sabem que pode ser descrito como uma coluna ‘integer’ ( internamente, ela foi executada infer_dtype) mas não deduziu exatamente que tipo de número inteiro deveria ter, portanto não o converteu. A coluna ‘b’ foi novamente convertida em dtype ‘string’, pois era reconhecida como mantendo valores de ‘string’

Método 2

Use isto:

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
df

Out[16]:
  one  two three
0   a  1.2   4.2
1   b   70  0.03
2   x    5     0

df.dtypes

Out[17]:
one      object
two      object
three    object

df[['two', 'three']] = df[['two', 'three']].astype(float)

df.dtypes

Out[19]:
one       object
two      float64
three    float64

Método 3

Este código abaixo alterará o tipo de dados de uma coluna.

df[['col.name1', 'col.name2'...]] = df[['col.name1', 'col.name2'..]].astype('data_type')

No lugar do tipo de dados, você pode fornecer ao seu tipo de dados o que deseja, como, str, float, int, etc.

Change column type in pandas

Esse conteudo foi traduzido e adaptado de stackoverflow

Veja mais em:

Principais plataformas RPA para desenvolvedores Python em 2022

Compartilhe!