pyspark заменяет все значения в датафрейме другими значениями - PullRequest
0 голосов
/ 01 октября 2018

У меня есть 500 столбцов в моем фрейме данных pyspark ... Некоторые имеют строковый тип, некоторые int и некоторые логические (100 логических столбцов).Теперь все логические столбцы имеют два разных уровня - Да и Нет, и я хочу преобразовать их в 1/0

. Для строки у меня есть три значения: пропущено, сбой и пусто.Как заменить эти нули на 0?fillna (0) работает только с целыми числами

 c1| c2 |    c3 |c4|c5..... |c500
yes| yes|passed |45....
No | Yes|failed |452....
Yes|No  |None   |32............

, когда я делаю

df.replace(yes,1)

Я получаю следующую ошибку:

ValueError: Mixed type replacements are not supported

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Вы должны попытаться использовать df.na.fill(), но проводя различие между столбцами в аргументах функции fill.

У вас будет что-то вроде:

df_test.na.fill({"value":"","c4":0}).show()
0 голосов
/ 02 октября 2018

Для строки у меня есть три значения: передано, сбой и ноль.Как заменить эти нули на 0?fillna (0) работает только с целыми числами

. Сначала импортируйте , когда и горит

from pyspark.sql.functions import when, lit

Предполагая, что в вашем DataFrame есть эти столбцы

# Reconstructing my DataFrame based on your assumptions
# cols are Columns in the DataFrame
cols = ['name', 'age', 'col_with_string']

# Similarly the values
vals = [
     ('James', 18, 'passed'),
     ('Smith', 15, 'passed'),
     ('Albie', 32, 'failed'),
     ('Stacy', 33, None),
     ('Morgan', 11, None),
     ('Dwight', 12, None),
     ('Steve', 16, 'passed'), 
     ('Shroud', 22, 'passed'),
     ('Faze', 11,'failed'),
     ('Simple', 13, None)
]

# This will create a DataFrame using 'cols' and 'vals'
# spark is an object of SparkSession
df = spark.createDataFrame(vals, cols)

# We have the following DataFrame
df.show()

+------+---+---------------+
|  name|age|col_with_string|
+------+---+---------------+
| James| 18|         passed|
| Smith| 15|         passed|
| Albie| 32|         failed|
| Stacy| 33|           null|
|Morgan| 11|           null|
|Dwight| 12|           null|
| Steve| 16|         passed|
|Shroud| 22|         passed|
|  Faze| 11|         failed|
|Simple| 13|           null|
+------+---+---------------+

Вы можете использовать:

  • withColumn () - указать столбец, который вы хотите использовать.
  • isNull () - Фильтр, который оценивается как true, если атрибут оценивается как ноль
  • lit () -создает столбец для литералов
  • когда () , в противном случае () - используется для проверки условия относительно столбца

Я могу заменить значения со значением NULL на 0

df = df.withColumn('col_with_string', when(df.col_with_string.isNull(), 
lit('0')).otherwise(df.col_with_string))

# We have replaced nulls with a '0'
df.show()

+------+---+---------------+
|  name|age|col_with_string|
+------+---+---------------+
| James| 18|         passed|
| Smith| 15|         passed|
| Albie| 32|         failed|
| Stacy| 33|              0|
|Morgan| 11|              0|
|Dwight| 12|              0|
| Steve| 16|         passed|
|Shroud| 22|         passed|
|  Faze| 11|         failed|
|Simple| 13|              0|
+------+---+---------------+

Часть 1 вашего вопроса: Да / Нет логических значений - вы упомянули, что есть 100 столбцов логических значений.Для этого я обычно восстанавливаю таблицу с обновленными значениями или создаю UDF, возвращающую 1 или 0 для Да или Нет.

Я добавляю еще два столбца can_vote и can_lotto в DataFrame (df)

df = df.withColumn("can_vote", col('Age') >= 18)
df = df.withColumn("can_lotto", col('Age') > 16) 

# Updated DataFrame will be
df.show()

+------+---+---------------+--------+---------+
|  name|age|col_with_string|can_vote|can_lotto|
+------+---+---------------+--------+---------+
| James| 18|         passed|    true|     true|
| Smith| 15|         passed|   false|    false|
| Albie| 32|         failed|    true|     true|
| Stacy| 33|              0|    true|     true|
|Morgan| 11|              0|   false|    false|
|Dwight| 12|              0|   false|    false|
| Steve| 16|         passed|   false|    false|
|Shroud| 22|         passed|    true|     true|
|  Faze| 11|         failed|   false|    false|
|Simple| 13|              0|   false|    false|
+------+---+---------------+--------+---------+

Предполагается, что у вас есть столбцы, аналогичные can_vote и can_lotto (логические значения Да / Нет)

Вы можете использовать следующую строку кода для извлечения столбцов в DataFrame, имеющих логический тип

col_with_bool = [item[0] for item in df.dtypes if item[1].startswith('boolean')]

Возвращает список

['can_vote', 'can_lotto']

Вы можете создать UDF и выполнить итерацию для каждого столбца в этом типе списка, освещая каждый из столбцов, используя 1 (Да) или 0 (Нет).

Для справки см. Следующие ссылки

0 голосов
/ 01 октября 2018

Я пытался повторить вашу проблему с данными ниже:

df_test=pd.DataFrame([['yes','pass',1.2],['No','pass',34],['yes',None,0.4],[0,1,'No'],['No',1,True],['NO','YES',1]])

, тогда я просто использую:

df_test.replace('yes',1)
...