簡體   English   中英

在pySpark中獲取每個組的前N個項目

[英]Getting Top N items per group in pySpark

我正在使用Spark 1.6.2,我具有以下數據結構:

sample = sqlContext.createDataFrame([
                    (1,['potato','orange','orange']),
                    (1,['potato','orange','yogurt']),
                    (2,['vodka','beer','vodka']),
                    (2,['vodka','beer','juice', 'vinegar'])

    ],['cat','terms'])

我想提取每只貓的前N個最常用術語。 我已經開發了以下似乎可行的解決方案,但是我想看看是否有更好的方法可以做到這一點。

from collections import Counter
def get_top(it, terms=200):
    c = Counter(it.__iter__())
    return [x[0][1] for x in c.most_common(terms)]

( sample.select('cat',sf.explode('terms')).rdd.map(lambda x: (x.cat, x.col))
 .groupBy(lambda x: x[0])
 .map(lambda x: (x[0], get_top(x[1], 2)))
 .collect()
)

它提供以下輸出:

[(1, ['orange', 'potato']), (2, ['vodka', 'beer'])]

這與我要尋找的內容一致,但是我真的不喜歡我訴諸使用Counter的事實。 僅憑火花怎么辦?

謝謝

如果此方法有效,最好將其發布到Code Review

就像我在沒有Counter的情況下執行此操作一樣,但是在很大程度上,您只是在復制相同的功能。

  • 計算( catterm )的每次出現
  • cat分組
  • 根據“計數”和“切片”將值排序為術語數( 2

碼:

from operator import add

(sample.select('cat', sf.explode('terms'))
 .rdd
 .map(lambda x: (x, 1))
 .reduceByKey(add)
 .groupBy(lambda x: x[0][0])
 .mapValues(lambda x: [r[1] for r, _ in sorted(x, key=lambda a: -a[1])[:2]])
 .collect())

輸出:

[(1, ['orange', 'potato']), (2, ['vodka', 'beer'])]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM