Quero 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 flutuadores? Existe uma maneira de especificar os tipos durante a conversão para o DataFrame? Ou é melhor criar o DataFrame primeiro e depois percorrer as colunas para alterar o tipo de cada coluna? Idealmente, eu gostaria de fazer isso de uma maneira dinâmica, porque pode haver centenas de colunas e não quero especificar exatamente quais colunas são de qual tipo. Tudo o que posso garantir é que cada coluna contenha valores do mesmo tipo.
df.apply(pd.to_numeric, downcast="integer", errors="ignore")
fazer o downcast de colunas inteiras para o menor (inteiro) dtype que conterá os valores.Respostas:
Você tem três opções principais para converter tipos em pandas:
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émto_datetime()
eto_timedelta()
.)astype()
- converta (quase) qualquer tipo para (quase) qualquer outro tipo (mesmo que não seja necessariamente sensato fazê-lo). Também permite converter para tipos categoriais (muito útil).infer_objects()
- um método utilitário para converter colunas de objetos contendo objetos Python em um tipo de panda, se possível.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á alterar objetos não numéricos (como seqüências de caracteres) em números 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.Como você pode ver, uma nova série é retornada. Lembre-se de atribuir esta saída a um nome de variável ou coluna para continuar usando:
Você também pode usá-lo para converter várias colunas de um DataFrame por meio do
apply()
método:Desde que todos os seus valores possam ser convertidos, é provavelmente tudo o 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 usa umerrors
argumento de palavra - chave que permite forçar a inclusão de valores não numéricosNaN
ou simplesmente ignorar as colunas que contêm esses valores.Aqui está um exemplo usando uma série de strings
s
que possui o objeto dtype:O comportamento padrão é aumentar se não puder converter um valor. Nesse caso, ele não pode lidar com a string 'pandas':
Em vez de falhar, podemos querer que 'pandas' sejam considerados um valor numérico ausente / ruim. Podemos coagir valores inválidos da
NaN
seguinte maneira usando oerrors
argumento de palavra - chave:A terceira opção para
errors
é apenas ignorar a operação se um valor inválido for encontrado:Essa última opção é particularmente útil quando você deseja converter todo o seu DataFrame, mas não sabe quais de nossas colunas podem ser convertidas de maneira confiável em um tipo numérico. Nesse caso, basta escrever:
A função será aplicada a cada coluna do DataFrame. As colunas que podem ser convertidas em um tipo numérico serão convertidas, enquanto as colunas que não puderem (por exemplo, que contêm strings ou datas que não sejam dígitos) serão deixadas em paz.
Downcasting
Por padrão, a conversão com
to_numeric()
fornecerá umint64
oufloat64
dtype (ou qualquer largura inteira nativa da sua plataforma).Isso é geralmente o que você deseja, mas e se você quiser economizar um pouco de memória e usar um tipo mais compacto, como
float32
ouint8
?to_numeric()
oferece a opção de fazer downcast para 'número inteiro', 'assinado', 'não assinado', 'flutuante'. Aqui está um exemplo para uma série simpless
de tipo inteiro:Downcasting para 'número inteiro' usa o menor número possível possível que pode conter os valores:
O downcasting para 'float' escolhe de maneira semelhante um tipo flutuante menor que o normal:
2)
astype()
O
astype()
método permite que você seja explícito sobre o tipo que você deseja que seu DataFrame ou Series tenha. É muito versátil, pois você pode tentar ir de um tipo para outro.Uso básico
Basta escolher um tipo: você pode usar um tipo NumPy (por exemplo
np.int16
), alguns tipos Python (por exemplo, bool) ou tipos específicos de pandas (como o tipo categórico).Chame o método no objeto que você deseja converter e
astype()
tentará convertê-lo para você:Observe que eu disse "tente" - se
astype()
não souber converter um valor na série ou no DataFrame, isso gerará um erro. Por exemplo, se você tiver um valorNaN
ou,inf
receberá um erro ao tentar convertê-lo em um número inteiro.No 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:Estes são números inteiros pequenos. Então, que tal converter para um tipo de 8 bits não assinado para economizar memória?
A conversão funcionou, mas o -7 foi arredondado para se tornar 249 (ou seja, 2 8 - 7)!
Tentar fazer o downcast usando
pd.to_numeric(s, downcast='unsigned')
pode ajudar a evitar 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 possuem um tipo de dados de objeto em um tipo mais específico (conversões flexíveis).Por exemplo, aqui está um DataFrame com duas colunas do tipo de objeto. Um contém inteiros reais e o outro contém cadeias que representam números inteiros:
Usando
infer_objects()
, você pode alterar o tipo de coluna 'a' para int64:A coluna 'b' foi deixada sozinha, pois seus valores eram cadeias de caracteres, não números inteiros. Se você quiser tentar forçar a conversão de ambas as colunas em um tipo inteiro, use-o
df.astype(int)
.fonte
.convert_objects
está obsoleto desde0.17
- use emdf.to_numeric
vez dissopd.to_numeric
e seus métodos complementares funcionarão apenas em uma coluna por vez, ao contrárioconvert_objects
. A discussão sobre uma função de substituição na API parece estar em andamento ; Espero que um método que funcione em todo o DataFrame permaneça porque é muito útil.int64
emint32
?astype
(como na outra resposta), ie.astype(numpy.int32)
.Que tal agora?
fonte
pd.DataFrame
tem umdtype
argumento que pode permitir que você faça o que você está procurando. df = pd.DataFrame (a, colunas = ['um', 'dois', 'três'], dtype = float) Em [2]: df.dtypes Out [2]: um objeto dois float64 três float64 dtype: objectSettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
. Isso pode ter sido introduzido em uma versão mais recente do pandas e, como resultado, não vejo nada de errado, mas me pergunto o que é esse aviso. Qualquer ideia?ValueError: Cannot convert NA to integer
df = pd.DataFrame(a, columns=['one', 'two', 'three'], dtype={'one': str, 'two': int, 'three': float})
. Estou tendo dificuldade em encontrar a especificação para os valores "dtype" aceitos. Uma lista seria legal (atualmente eu façodict(enumerate(my_list))
).este código abaixo mudará o tipo de dados da coluna.
no lugar do tipo de dados, você pode fornecer ao seu tipo de dados o que você deseja como str, float, int etc.
fonte
bool
, tudo é alterado paraTrue
.Quando só preciso especificar colunas específicas e quero ser explícito, usei (por DOCS LOCATION ):
Então, usando a pergunta original, mas fornecendo nomes de colunas para ela ...
fonte
Aqui está uma função que usa como argumento um DataFrame e uma lista de colunas e coage todos os dados nas colunas para números.
Então, para o seu exemplo:
fonte
Que tal criar dois quadros de dados, cada um com diferentes tipos de dados para suas colunas e anexá-los juntos?
Resultados
Após a criação do quadro de dados, é possível preenchê-lo com variáveis de ponto flutuante na 1ª coluna e seqüências de caracteres (ou qualquer tipo de dados desejado) na 2ª coluna.
fonte
pandas> = 1.0
Aqui está um gráfico que resume algumas das conversões mais importantes em pandas.
Conversões para string são triviais
.astype(str)
e não são mostradas na figura.Conversões "rígidas" versus "flexíveis"
Observe que "conversões" nesse contexto pode se referir à conversão de dados de texto em seu tipo de dados real (conversão rígida) ou inferir tipos de dados mais apropriados para dados em colunas de objetos (conversão suave). Para ilustrar a diferença, dê uma olhada
fonte
Eu pensei que tinha o mesmo problema, mas na verdade tenho uma pequena diferença que facilita a solução do problema. Para outras pessoas que olham para essa pergunta, vale a pena verificar o formato da sua lista de entradas. No meu caso, os números são inicialmente flutuadores e não cordas, como na pergunta:
mas processando muito a lista antes de criar o quadro de dados, perco os tipos e tudo se torna uma string.
Criando o quadro de dados por meio de uma matriz numpy
fornece o mesmo quadro de dados da pergunta, em que as entradas nas colunas 1 e 2 são consideradas como cadeias. No entanto fazendo
na verdade, fornece um quadro de dados com as colunas no formato correto
fonte
A partir do pandas 1.0.0, temos
pandas.DataFrame.convert_dtypes
. Você pode até controlar quais tipos converter!fonte
Converta várias colunas do tipo de dados !
fonte