Как написать Pyspark UDF для генерации всех возможных комбинаций итогов столбцов?

У меня есть следующий код, который создает новый столбец на основе комбинаций столбцов в моем фрейме данных, за вычетом дубликатов:

import itertools as it
import pandas as pd 

df = pd.DataFrame({
  'a': [3,4,5,6,3], 
  'b': [5,7,1,0,5], 
  'c': [3,4,2,1,3], 
  'd': [2,0,1,5,9]
})

orig_cols = df.columns 
for r in range(2, df.shape[1] + 1):
    for cols in it.combinations(orig_cols, r):
        df["_".join(cols)] = df.loc[:, cols].sum(axis=1)

df

Мне нужно получить те же результаты, используя Pyspark через UDF. Каким будет эквивалентный код в Pyspark?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Нет необходимости использовать UDF. Давайте использовать собственные искровые функции:

from itertools import combinations

sums = [
    sum(map(F.col, c)).alias('_'.join(c)) 
    for r in range(2, len(df.columns) + 1) 
    for c in combinations(df.columns,   r)
]

df = df.select('*', *sums)

df.show()

+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+-------+
|  a|  b|  c|  d|a_b|a_c|a_d|b_c|b_d|c_d|a_b_c|a_b_d|a_c_d|b_c_d|a_b_c_d|
+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+-------+
|  3|  5|  3|  2|  8|  6|  5|  8|  7|  5|   11|   10|    8|   10|     13|
|  4|  7|  4|  0| 11|  8|  4| 11|  7|  4|   15|   11|    8|   11|     15|
|  5|  1|  2|  1|  6|  7|  6|  3|  2|  3|    8|    7|    8|    4|      9|
|  6|  0|  1|  5|  6|  7| 11|  1|  5|  6|    7|   11|   12|    6|     12|
|  3|  5|  3|  9|  8|  6| 12|  8| 14| 12|   11|   17|   15|   17|     20|
+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+-------+

Спасибо... предположим, что df выше имеет дату в первом столбце с остальными столбцами, как показано. Как мне изменить код, чтобы результирующий df выглядел так, как показано выше?

jack homareau 14.04.2023 21:25

Замените df.columns на df.columns[1:] в обоих местах.

Shubham Sharma 15.04.2023 06:40

Это версия вашего кода для PySpark. Вы можете изменить функцию UDF и ее регистрацию по своему усмотрению.

data = [
    (3,4,5,6), 
    (5,7,1,0), 
    (3,4,2,1), 
    (2,0,1,5)
]

col_names = ['a', 'b', 'c', 'd']
df = spark.createDataFrame(data, col_names)

combination_cols = []
for r in range(2, df.count()):
    combination_cols += it.combinations(col_names, r)

def do_something(*args):
    result = 0
    for x in args:
        result += x
    return result

do_something_udf = udf(do_something, IntegerType())

output_df = df
for tup in combination_cols:
    output_df = output_df.withColumn("_".join(tup), do_something_udf(*tup))

output_df.show()

Выход:

+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+
|  a|  b|  c|  d|a_b|a_c|a_d|b_c|b_d|c_d|a_b_c|a_b_d|a_c_d|b_c_d|
+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+
|  3|  4|  5|  6|  7|  8|  9|  9| 10| 11|   12|   13|   14|   15|
|  5|  7|  1|  0| 12|  6|  5|  8|  7|  1|   13|   12|    6|    8|
|  3|  4|  2|  1|  7|  5|  4|  6|  5|  3|    9|    8|    6|    7|
|  2|  0|  1|  5|  2|  3|  7|  1|  5|  6|    3|    7|    8|    6|
+---+---+---+---+---+---+---+---+---+---+-----+-----+-----+-----+

Другие вопросы по теме