Выберите самый старый столбец для сгруппированного кадра данных искры - PullRequest
0 голосов
/ 05 июля 2019

Учитывая фрейм данных (df) со следующими столбцами:

id,
created_date,
name

Мне нужно убедиться, что все строки с одинаковыми именами имеют одинаковый идентификатор.Я могу создать отображение от старого идентификатора до нового идентификатора (выбранный в «случайном» порядке, используя max).

df.groupBy('name')\
  .agg(
    func.max('id').alias('new_id'),                         
    func.collect_set(id).alias('grouped_ids'))\
  .filter(func.size('grouped_ids') > 1)\                
  .select(func.explode("grouped_ids").alias('old_id'), "new_id")\
  .filter("new_id != old_id")

Я могу присоединить левую стрелку к исходному df (on id = old_id) и поменять местами идентификаторыесли есть доступный new_id.

Тем не менее, я должен убедиться, что выбран новый_идид с тем, который имеет самую старую дату create_date в кадре данных (а не просто выбирая max).

Как лучшечтобы пойти по этому поводу?

Например, учитывая данные

id, created_date, name
---
17a, 2019-01-05, Jeff
17a, 2019-01-03, Jeremy
d21, 2019-01-04, Jeremy
u45, 2019-01-04, Jeremy
d21, 2019-01-02, Scott
x22, 2019-01-01, Julian

Строки 2, 3 и 4 группы на Джереми, поэтому должны иметь одинаковый идентификатор.Самым старым идентификатором в кадре данных для сгруппированных идентификаторов является d21, так как в строке 5 значение create_date - 2019-01-02, поэтому его следует выбрать и применить ко всем строкам в кадре данных с другими сгруппированными идентификаторами, и в итоге мы получим:

id, created_date, name
---
d21, 2019-01-05, Jeff
d21, 2019-01-03, Jeremy
d21, 2019-01-04, Jeremy
d21, 2019-01-04, Jeremy
d21, 2019-01-02, Scott
x22, 2019-01-01, Julian

ОБНОВЛЕНИЕ: @Charles Du - Cheers, я попробовал ваш код, но он не сработал, самый старый идентификатор был выбран из сгруппированных имен, а не df какцелом и new_id не был применен на протяжении всей df.

Result:
0 = {Row} Row(name='Scott', created_date='2019-01-02', new_ID='d21', id='d21', created_date='2019-01-02')
1 = {Row} Row(name='Julian', created_date='2019-01-01', new_ID='x22', id='x22', created_date='2019-01-01')
2 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='17a', created_date='2019-01-03')
3 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='d21', created_date='2019-01-04')
4 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='u45', created_date='2019-01-04')
5 = {Row} Row(name='Jeff', created_date='2019-01-05', new_ID='17a', id='17a', created_date='2019-01-05')

1 Ответ

0 голосов
/ 05 июля 2019

Мой сплитбол здесь

from pyspark.sql import functions as F

new_df = df.groupBy('name').agg(F.min('date'))

new_df = new_df.join(df, on=['name', 'date'], how='inner')

# This should give you a df with a single record for each name with the oldest ID.

new_df = new_df.withColumnRenamed('id', 'new_ID')

#you'll need to decide on a naming convention for your date column since you'll have two if you don't rename

res = new_df.join(df, on='name', how='inner)

, который должен соответствовать вашему идентификатору с самой старой датой.

...