2016-10-18 12 views
2

にいくつかの列を持つGROUPBYから最大値で行を取得する私はPySpark

from pyspark.sql.functions import avg, first 

rdd = sc.parallelize(
[ 
(0, "A", 223,"201603", "PORT"), 
(0, "A", 22,"201602", "PORT"), 
(0, "A", 22,"201603", "PORT"), 
(0, "C", 22,"201605", "PORT"), 
(0, "D", 422,"201601", "DOCK"), 
(0, "D", 422,"201602", "DOCK"), 
(0, "C", 422,"201602", "DOCK"), 
(1,"B", 3213,"201602", "DOCK"), 
(1,"A", 3213,"201602", "DOCK"), 
(1,"C", 3213,"201602", "PORT"), 
(1,"B", 3213,"201601", "PORT"), 
(1,"B", 3213,"201611", "PORT"), 
(1,"B", 3213,"201604", "PORT"), 
(3,"D", 3999,"201601", "PORT"), 
(3,"C", 323,"201602", "PORT"), 
(3,"C", 323,"201602", "PORT"), 
(3,"C", 323,"201605", "DOCK"), 
(3,"A", 323,"201602", "DOCK"), 
(2,"C", 2321,"201601", "DOCK"), 
(2,"A", 2321,"201602", "PORT") 
] 
) 
df_data = sqlContext.createDataFrame(rdd, ["id","type", "cost", "date", "ship"]) 

に似たデータフレームを持っていると私はidtypeにより集約し、グループごとにshipの最高発生を取得する必要があります。例えば、

grouped = df_data.groupby('id','type', 'ship').count() 

は、各グループの回数を持つ列があります。

+---+----+----+-----+ 
| id|type|ship|count| 
+---+----+----+-----+ 
| 3| A|DOCK| 1| 
| 0| D|DOCK| 2| 
| 3| C|PORT| 2| 
| 0| A|PORT| 3| 
| 1| A|DOCK| 1| 
| 1| B|PORT| 3| 
| 3| C|DOCK| 1| 
| 3| D|PORT| 1| 
| 1| B|DOCK| 1| 
| 1| C|PORT| 1| 
| 2| C|DOCK| 1| 
| 0| C|PORT| 1| 
| 0| C|DOCK| 1| 
| 2| A|PORT| 1| 
+---+----+----+-----+ 

をし、私は

の組み合わせを使用しようとした

+---+----+----+-----+ 
| id|type|ship|count| 
+---+----+----+-----+ 
| 0| D|DOCK| 2| 
| 0| A|PORT| 3| 
| 1| A|DOCK| 1| 
| 1| B|PORT| 3| 
| 2| C|DOCK| 1| 
| 2| A|PORT| 1| 
| 3| C|PORT| 2| 
| 3| A|DOCK| 1| 
+---+----+----+-----+ 

を取得する必要があります

grouped.groupby('id', 'type', 'ship')\ 
.agg({'count':'max'}).orderBy('max(count)', ascending=False).\ 
groupby('id', 'type', 'ship').agg({'ship':'first'}) 

ただし、失敗します。グループのカウントから最大の行を取得する方法はありますか?パンダで

このonelinerが仕事をしていません:あなたの期待出力に基づいて

df_pd = df_data.toPandas() 
df_pd_t = df_pd[df_pd['count'] == df_pd.groupby(['id','type', ])['count'].transform(max)] 
+0

可能な重複(http://stackoverflow.com/questions/35218882/find-maximum-:

これを達成するために、我々は、Window機能を使用することができ –

+0

指定された投稿にはグループの次元が1つだけあります。そのポストの3つの方法でそれをどのように拡張するのかは明らかではありません。 – Ivan

+0

答えには影響しません。 partitionByまたはgroupByに入れるだけです。 –

答えて

3

、あなたが唯一のidshipによってグループ化されているようです - あなたはすでにgroupedで異なる値を持っているので - その結果、重複した要素をドロップid,shipおよびcountに基づいて、typeでソートされています。 【スパークデータフレームのグループごとの最大行を検索]の

from pyspark.sql.window import Window 
from pyspark.sql.functions import rank, col 

window = (Window 
      .partitionBy(grouped['id'], 
         grouped['ship']) 
      .orderBy(grouped['count'].desc(), grouped['type'])) 


(grouped 
.select('*', rank() 
     .over(window) 
     .alias('rank')) 
    .filter(col('rank') == 1) 
    .orderBy(col('id')) 
    .dropDuplicates(['id', 'ship', 'count']) 
    .drop('rank') 
    .show()) 
+---+----+----+-----+ 
| id|type|ship|count| 
+---+----+----+-----+ 
| 0| D|DOCK| 2| 
| 0| A|PORT| 3| 
| 1| A|DOCK| 1| 
| 1| B|PORT| 3| 
| 2| C|DOCK| 1| 
| 2| A|PORT| 1| 
| 3| A|DOCK| 1| 
| 3| C|PORT| 2| 
+---+----+----+-----+