Как изменить типы нескольких столбцов в pyspark?

#python #select #types #casting #pyspark

#python #выберите #типы #Кастинг #pyspark

Вопрос:

Я только изучаю pyspark. Я хочу изменить типы столбцов следующим образом:

 df1=df.select(df.Date.cast('double'),df.Time.cast('double'),
          df.NetValue.cast('double'),df.Units.cast('double'))
  

Вы можете видеть, что df — это фрейм данных, и я выбираю 4 столбца и меняю все из них на double. Из-за использования select все остальные столбцы игнорируются.

Но, если в df сотни столбцов, и мне просто нужно изменить эти 4 столбца. Мне нужно сохранить все столбцы. Итак, как это сделать?

Ответ №1:

Попробуйте это:

 from pyspark.sql.functions import col

df = df.select([col(column).cast('double') for column in df.columns])
  

Комментарии:

1. Это приятно, но это не позволяет вам обновлять df на месте, как в ответе выше

2. Честно говоря, не уверен, что вы правы, фреймы данных AFAIK Spark неизменяемы и, следовательно, не могут быть обновлены на месте. И даже если бы вы могли, я не понимаю, как приведенное выше решение могло бы обновлять что-либо на месте. Если у вас есть ссылка для резервного копирования вашего заявления, мне было бы интересно прочитать.

3. Хорошо, позвольте мне перефразировать. Я не имею в виду in place, как в pandas, где вы можете установить параметр in place. Я имею в виду, что это не позволяет мне обновлять df в одной строке. Одна строка всегда более профессиональна, особенно по сравнению с циклом for.

4. Вообще не понимаю. Мое решение — это 1 строка, принятый ответ запускает оператор для каждого столбца, требующий приведения, т. е. прямую противоположность тому, что вы говорите

5. На самом деле он возвращает все столбцы набора данных (обновленные). Чего он не делает, так это допускает дифференцированную обработку подмножества столбцов, что и было сделано в принятом ответе (и, предположительно, то, что хотел OP). Итак, еще раз, ваше утверждение неверно.

Ответ №2:

 for c in df.columns:
    # add condition for the cols to be type cast
    df=df.withColumn(c, df[c].cast('double'))
  

Комментарии:

1. @ags29 работает с небольшими наборами данных, у меня есть 2 тысячи столбцов с примерно 200 тысячами записей. Хотел преобразовать все в целое число, кроме 3 столбцов. Это займет целую вечность! Есть предложения?

Ответ №3:

Другой способ, использующий selectExpr() :

 df1 = df.selectExpr("cast(Date as double) Date", 
    "cast(NetValueas string) NetValue")
df1.printSchema()
  

Используя withColumn() :

 from pyspark.sql.types import DoubleType, StringType

df1 = df.withColumn("Date", df["Date"].cast(DoubleType())) 
      .withColumn("NetValueas ", df["NetValueas"].cast(StringType()))
df1.printSchema()
  

Проверьте документацию по типам.

Ответ №4:

Я понимаю, что вы хотели бы получить ответ, не относящийся к циклу, который сохраняет исходный набор столбцов, обновляя при этом только подмножество. Следующий должен быть ответом, который вы искали:

 from pyspark.sql.functions import col

df = df.select(*(col(c).cast("double").alias(c) for c in subset),*[x for x in df.columns if x not in subset])
  

где subset находится список имен столбцов, которые вы хотели бы обновить.