Как разделить элементы одного столбца DataFrame на несколько

1
8

Я пытаюсь разделить столбец DataFrame score на несколько разных столбцов, но у меня возникают проблемы, потому что он сообщает мне, что if let scoreColumn = gameTrainingData["score"] as? Column<Dictionary<String, Optional<Any>>> всегда будет завершаться ошибкой, даже если это тип столбца. Я проверил документацию, чтобы узнать, есть ли встроенная функция для этого, но ее там нет.

Вот что у меня есть на данный момент:

Если кто-то может дать отзыв о том, как правильно создавать новые столбцы из элементов одного столбца для обучения модели, я был бы очень признателен.

Вот столбец score в виде данных JSON:

// Extract relevant information from the 'score' column
        if let scoreColumn = gameTrainingData["score"] as? Column<Dictionary<String, Optional<Any>>>  {
            let winnerColumn = scoreColumn.map { ($0!["winner"] as? String) ?? "UNKNOWN" }
            let fullTimeHomeColumn = scoreColumn.map { ($0!["fullTime"] as? [String: Int])?["home"] ?? -1 }
            let fullTimeAwayColumn = scoreColumn.map { ($0!["fullTime"] as? [String: Int])?["away"] ?? -1 }
            
            // Add these as new columns to the DataFrame
            gameTrainingData.append(column: Column(name: "winner", contents: winnerColumn))
            gameTrainingData.append(column: Column(name: "fullTimeHome", contents: fullTimeHomeColumn))
            gameTrainingData.append(column: Column(name: "fullTimeAway", contents: fullTimeAwayColumn))
        }
        
        // Define feature columns based on the extracted data
        let featureColumns = [
            "homeTeam",
            "awayTeam",
            "fullTimeHome",
            "fullTimeAway",
            "referees"
        ]
        
        // Model Setup
        let parameters = MLRandomForestClassifier.ModelParameters(
            validation: .split(strategy: .automatic),
            maxIterations: 100,
            randomSeed: 38
        )
        
        let model = try MLRandomForestClassifier(
            trainingData: gameTrainingData,
            targetColumn: "winner", // Assuming you're predicting the winner
            featureColumns: featureColumns,
            parameters: parameters
        )
"score": {
    duration = REGULAR;
    fullTime =     {
        away = 0;
        home = 2;
    };
    halfTime =     {
        away = 0;
        home = 0;
    };
    winner = "HOME_TEAM";
}
Автоном
Вопрос задан4 февраля 2024 г.

1 Ответ

2

Разделение элементов одного столбца DataFrame на несколько новых столбцов в Apache Spark (с использованием PySpark) может быть выполнено несколькими способами. Выбор метода зависит от типа разделения и желаемого результата. 

1. Разделение по разделителю:

  • Используйте split() и withColumn():

    from pyspark.sql.functions import split, col
    
    # Предположим, что ваш DataFrame называется `df` 
    # и столбец для разделения называется `column_to_split`
    # Разделитель - " " (пробел)
    df = df.withColumn("new_column1", split(col("column_to_split"), " ")[0])
    df = df.withColumn("new_column2", split(col("column_to_split"), " ")[1]) 
    # ... (добавьте столько новых столбцов, сколько нужно)
    
    df.show()
    

    Этот код делит строку в column_to_split по пробелу (” “) и создает новые столбцы new_column1new_column2 и т.д. с соответствующими частями строки.

  • Используйте withColumnRenamed():

    from pyspark.sql.functions import split, col
    
    # Предположим, что ваш DataFrame называется `df` 
    # и столбец для разделения называется `column_to_split`
    # Разделитель - " " (пробел)
    df = df.withColumn("column_to_split", split(col("column_to_split"), " "))
    df = df.withColumnRenamed("column_to_split[0]", "new_column1") 
    df = df.withColumnRenamed("column_to_split[1]", "new_column2") 
    # ... (переименуйте остальные элементы массива)
    
    df.show()
    

    В этом варианте вы сохраняете результат split() в исходный столбец и затем переименовываете элементы массива в новые столбцы.

2. Разделение по размеру:

  • Используйте substring() и withColumn():

    from pyspark.sql.functions import substring, col
    
    # Предположим, что ваш DataFrame называется `df` 
    # и столбец для разделения называется `column_to_split`
    # Разделение на части по 3 символа
    df = df.withColumn("new_column1", substring(col("column_to_split"), 1, 3))
    df = df.withColumn("new_column2", substring(col("column_to_split"), 4, 6))
    # ... (добавьте столько новых столбцов, сколько нужно)
    
    df.show()
    

    Этот код извлекает подстроки из column_to_split заданной длины и создает новые столбцы.

3. Разделение по условию:

  • Используйте when() и otherwise():

    from pyspark.sql.functions import when, col
    
    # Предположим, что ваш DataFrame называется `df` 
    # и столбец для разделения называется `column_to_split`
    # Разделение по наличию "-"
    df = df.withColumn("new_column1", when(col("column_to_split").contains("-"), split(col("column_to_split"), "-")[0]).otherwise(col("column_to_split")))
    df = df.withColumn("new_column2", when(col("column_to_split").contains("-"), split(col("column_to_split"), "-")[1]).otherwise(None))
    
    df.show()
    

    Этот код создает новые столбцы, основываясь на условии (в данном случае наличие “-“).

Дополнительные советы:

  • Используйте udf() для более сложных логик: Если стандартные функции не справляются с вашими потребностями, используйте User Defined Functions (UDF) для создания собственной логики разделения.
  • Оптимизируйте производительность: При работе с большими DataFrame, оптимизируйте код для достижения максимальной производительности. Используйте такие методы, как  broadcast() или  partitionBy(), чтобы эффективнее распределять данные в кластере.

Важно: Правильно выберите метод разделения, основываясь на конкретных требованиях вашей задачи и формате данных в DataFrame.

 

Радислав
Ответ получен6 сентября 2024 г.

Ваш ответ

Загрузить файл.