есть df вида (упрощенно):
| class | name | sum | year | ----------------------- | a | abc | 123 | 1999 | | a | def | 125 | 1999 | | a | ikl | 127 | 1999 | | a | mn | 201 | 2000 | | a | opr | 202 | 2000 |
значения в колонка class в данном примере одно - а (в общем случае много…), sum, year - int
надо получить df c максимальным sum по каждому уникальному значению year, т.е. результат должен быть таким:
| class| 1999 | 2000 | --------------------- | a | ikl | opr |
я делаю так (с некоторыми упрощениями и уже полученной подсказкой):
#размерность по оси Х: Х=df.select('year').distinct() #размерность по оси Y (в нашем примере это единственное значение): Y=df.select('class').distinct() #создаем df результата: st=StructField('class', StringType(), True) schema =StructType().add(st) for i in X.collect(): st=StructField(str(i[0]), StringType(), True) schema =schema.add(st) rez=sc.createDataFrame([], schema) for i0 in Y.collect(): a=i0[0] sz=[(a)] #накладываем фильтр по class df2=df.filter(df.class==a) i1=0 while i1<=X.count()-1: year=X.collect()[i1][0] #текущее значение по Х #накладываем фильтр по year df3=df2.filter(df2.year==year) #далее при помощи метода из библиотеки Pandas: pd=df3.toPandas() max=pd.loc[pd['sum']==pd['sum'].max()] name=max['name'].values[0] sz.append(name) i1=i1+1 #Добавляем строку в rez: st=sc.createDataFrame(Row(sz), schema) rez=rez.unionByName(st)
очевидно двойный цикл с обращением к Pandas внутри крайне не оптимально….
думаю что размерность (Х*Y) результирующего контейнера в любом случае надо получать
отдельно (в общем случае надо предусмотреть сортировку коллекций Х,У по возрастанию, удаление null..)
потом по “очищенным” и отсортированным Х,У формируем результирующий df (пустой)…
а вот его “наполнение” хотелось бы конечно не циклами…
альтернативная тактика: не формировать пустой контейнер, сразу неким образом получить df и уже после этого сортировать и очищать от null, однако есть сомнения что такая тактика даст выигрыш по времени исполнения, но главное нет уверенности в качестве результата… проблема в том, что в общем случае в коллекциях Х,У кроме null могут быть значения “неправильных” типов (например в колонке year - строки), и “вычищать” их из итогового df может оказаться не тривиальной задачей…