Alterar o tipo de coluna de string para float no Pandas

user1642513

Desejo converter uma tabela, representada como uma lista de listas, em um Pandas DataFrame. Como um exemplo extremamente simplificado:

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

Qual é a melhor maneira de converter as colunas nos tipos apropriados, neste caso as colunas 2 e 3 em flutuantes? Existe uma maneira de especificar os tipos ao converter para DataFrame? Ou é melhor criar o DataFrame primeiro e, em seguida, percorrer as colunas para alterar o tipo de cada coluna? Idealmente, gostaria de fazer isso de forma 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.

Alex Riley

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) em um tipo numérico adequado. (Veja também to_datetime()e to_timedelta().)

  2. astype()- converter (quase) qualquer tipo em (quase) qualquer outro tipo (mesmo que não seja necessariamente sensato fazer isso). Também permite a conversão para tipos categóricos (muito útil).

  3. infer_objects() - um método utilitário para converter colunas de objetos contendo objetos Python em um tipo de pandas, se possível.

  4. convert_dtypes()- converter colunas DataFrame para o "melhor possível" dtype que suporta pd.NA(objeto do pandas para indicar um valor ausente).

Continue lendo para obter explicações mais detalhadas e o uso 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á transformar objetos não numéricos (como strings) em inteiros ou números 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 esta saída a uma variável ou nome de coluna para continuar a usá-la:

# 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 por meio 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, isso provavelmente é tudo de que você precisa.

Manipulação de erros

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

to_numeric()também aceita um errorsargumento de palavra - chave que permite que você force valores não numéricos NaNou simplesmente ignore as colunas que contêm esses valores.

Aqui está um exemplo usando uma série de strings sque tem 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 consegue lidar com a string '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 / incorreto. Podemos forçar valores inválidos da NaNseguinte maneira, usando o errorsargumento de 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 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 quando você deseja converter seu DataFrame inteiro, mas não sabe qual das nossas colunas pode ser convertida de forma 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 strings ou datas sem dígitos) serão deixadas sozinhas.

Downcasting

Por padrão, a conversão com to_numeric()dará a você um int64ou float64dtype (ou qualquer largura inteira que seja nativa para sua plataforma).

Normalmente é isso que você quer, mas e se você quisesse economizar memória e usar um tipo de d mais compacto, como float32ou int8?

to_numeric()dá a você a opção de fazer downcast para 'inteiro', 'assinado', 'não assinado' ou 'flutuante'. Aqui está um exemplo de uma série simples sde tipo inteiro:

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

O downcasting para 'inteiro' usa o menor inteiro possível que pode conter os valores:

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

O downcasting para 'flutuar' da mesma forma escolhe um tipo flutuante menor do que o normal:

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

2 astype()

O astype()método permite que você seja explícito sobre o dtype que deseja que seu DataFrame ou Series tenha. É muito versátil na medida em que pode experimentar e ir de um tipo para o 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 tipo d categórico).

Chame o método no objeto que 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 "tentar" - se astype()não souber como converter um valor na Série ou DataFrame, ocorrerá um erro. Por exemplo, se você tiver um valor NaNou, infobterá um erro ao tentar convertê-lo em um inteiro.

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

Seja cuidadoso

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

São números inteiros pequenos, então que tal converter para um tipo de 8 bits sem sinal para economizar memória?

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

A conversão funcionou, mas o -7 foi enrolado para se tornar 249 (ou seja, 2 8 - 7)!

Tentar fazer o downcast usando em pd.to_numeric(s, downcast='unsigned')vez disso pode ajudar a prevenir esse erro.


3 - infer_objects()

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

Por exemplo, aqui está um DataFrame com duas colunas de tipo de objeto. Um contém números inteiros reais e o outro contém strings que representam 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 strings, não inteiros. Se você quiser tentar forçar a conversão de ambas as colunas em um tipo inteiro, poderá usar df.astype(int).


4 - convert_dtypes()

A versão 1.0 e superior incluem um método convert_dtypes()para converter colunas Series e DataFrame para o melhor dtype possível que suporta o pd.NAvalor ausente.

Aqui, "melhor possível" significa o tipo mais adequado para conter os valores. Por exemplo, este é um tipo inteiro pandas se todos os valores forem inteiros (ou valores ausentes): uma coluna de objeto de objetos inteiros Python é convertida para Int64, uma coluna de int32valores NumPy se tornará o tipo dpandas Int32.

Com nosso objectDataFrame df, obtemos o seguinte resultado:

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

Como a coluna 'a' continha valores inteiros, ela foi convertida para o Int64tipo (que é capaz de conter valores ausentes, ao contrário int64).

A coluna 'b' continha objetos string, então foi alterada para stringdtype dos pandas .

Por padrão, este 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 como uma coluna de objeto: o pandas sabe que ela pode ser descrita como uma coluna 'inteira' (ela foi executada internamente infer_dtype), mas não inferiu exatamente que tipo de inteiro deveria ter, então não a converteu. A coluna 'b' foi novamente convertida para o tipo d 'string', pois foi reconhecida como contendo valores de 'string'.

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

Como alterar o tipo de dados de uma coluna de STRING para TEXT no ORM Symfony 4?

pandas não está convertendo string de tipo para float

Como alterar o tipo de dados para uma única coluna para vários dataframes em pandas?

Alterar o tipo de coluna de string para data em Pyspark

Incapaz de alterar a coluna varchar para o tipo de data

Alterar o tipo de coluna de texto para inteiro

Google Big Query: como alterar o tipo de dados de string para float?

Como alterar o tipo de COLUNA existente para SERIAL no postgres?

Laravel - Como alterar o tipo de coluna (smallInteger => string)

Como alterar o tipo de dados do hive de string para array multidimensional para dividir a coluna corretamente

PG :: Erro de fuso horário ao alterar a coluna da string para o tipo de dados de tempo

Como converter o tipo de dados de uma coluna de String para List no pandas?

Como alterar o tipo de coluna em pandas sem nome de coluna?

Podemos alterar o tipo de coluna no Parse

Postgres: atualiza o tipo de coluna e analisa o valor da coluna de json para float

Como alterar o tipo de dados da coluna, referenciando outra tabela que tem detalhes de tipo de coluna no pandas?

Como alterar o tipo de dados da coluna, referenciando outra tabela que tem detalhes de tipo de coluna no pandas?

Converta uma coluna no dataframe do pandas de String para Float

Pyspark mudando o tipo de coluna de data para string

Pandas Dataframe Coluna inteira para tipo de dados String

O tipo de coluna DataFrame não muda para string

Alterar o tipo de dados de uma coluna específica de um dataframe pandas

Como alterar o tipo de uma coluna de caractere para ordinal em um quadro de dados?

Como posso alterar o tipo de dados de uma coluna de inteiro para texto no SQL Server?

Como alterar o tipo de dados de bytea [] para bytea de coluna no PostgreSQL?

pandas mudam o tipo de coluna para datetime afterr group

migração laravel para alterar o tipo de coluna usado em uma visualização

Alterar o tipo de valores de um array estranho de float para int

Tipo de coluna de conversão de SQL de float para varchar

TOP lista

quentelabel

Arquivo