2
respostas

[Aula de Tratamento de dados] Cast de String para Double não está funcionando direito

O professor usa o seguinte código para transformar algumas colunas do dataframe "dataset" de string para double:

dataset\
    .withColumn('usableAreas', dataset['usableAreas'].cast(IntegerType()))\
    .withColumn('price', dataset['price'].cast(DoubleType()))\
    .withColumn('condo', dataset['condo'].cast(DoubleType()))\
    .withColumn('iptu', dataset['iptu'].cast(DoubleType()))\
    .printSchema()

E quando eu uso o dataset.printSchema ele mostra que realmente viraram double, porém quando eu uso dataset.show( ) a aparência das linhas das colunas que são double ficam como se fossem int:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

O que será que está acontecendo? Eu tentei criar novas colunas baseadas nessas colunas e usei a função round, e aí deu certo, porém depois eu não consigo deletar as colunas antigas para ficar com as colunas novas. Quando uso a função dataset.drop("coluna"), ele dá o seguinte erro:

AttributeError: 'NoneType' object has no attribute 'drop'

2 respostas

Olá, Paulo, tudo bem?

Notei no seu código que você as alterações de tipagem são feitas no dataset. No entanto, reforço que é necessário armazenar o resultado das operações em uma variável se você deseja manter as alterações feitas no dataset original. Isso é feito através do código:

dataset = dataset\
    .withColumn('usableAreas', dataset['usableAreas'].cast(IntegerType()))\
    .withColumn('price', dataset['price'].cast(DoubleType()))\
    .withColumn('condo', dataset['condo'].cast(DoubleType()))\
    .withColumn('iptu', dataset['iptu'].cast(DoubleType()))

Feito isso, ao fazer dataset.show(), veremos as colunas com o tipo Double.

Quanto ao erro que você recebeu, AttributeError: 'NoneType' object has no attribute 'drop' aponta que o objeto dataset ao qual você está tentando aplicar o método drop é None. Isso geralmente ocorre quando você faz uma operação em dataset que não retorna um DataFrame, mas você tenta usar o resultado como se fosse um DataFrame. No Spark, operações como withColumn e drop não modificam o DataFrame original; elas retornam um novo DataFrame. Portanto, você precisa garantir que está utilizando o DataFrame retornado. Por exemplo:

dataset = dataset.drop("coluna_antiga")

Diante dos pontos que abordei, saliento que você deve sempre certificar de que está sempre atribuindo o resultado a dataset ou a uma nova variável DataFrame após cada operação que modifica o DataFrame.

Espero ter ajudado e fico à disposição.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Consegui passar dessa parte sem precisar usar o método drop, fazendo esse esquema de sempre atribuir o resultado a dataset eu consegui alterar as colunas utilizando f.round() e deu certo.

Porém voltou a dar erro na parte seguinte da aula quando ele faz uma query no data set


dataset = dataset\
              .select('usage')\
              .groupBy('usage')\
              .count()\
              .show()

Ele volta a dar o erro de "Nonetype" object has no attribute 'select':

Insira aqui a descrição dessa imagem para ajudar na acessibilidade