1

の列のユニークな組み合わせのためは、IがCOL1の一意の組合せの最初の行だけを必要と私はデータフレームの次のデータを有するデータフレーム

col1 col2 col3 col4 
1  desc1 v1  v3 
2  desc2 v4  v2 
1  desc1 v4  v2 
2  desc2 v1  v3 

を任意の行を取得

Expected Output: 

col1 col2 col3 col4 
1  desc1 v1  v3 
2  desc2 v4  v2 
以下のようCOL2

これをpyspark(バージョン1.3.1)でどうすれば実現できますか?

データフレームをrddに変換してからmapおよびreduceByKey関数を適用し、結果rddをデータフレームに変換することで、同じことを試みました。データフレーム関数を使用して上記の操作を実行する他の方法はありますか?

+1

論理的に考慮する必要はありますか? – eliasah

+0

これを明確にするには:最初/最後の行は必須ではありません。私は、同じ行から(col3、col4)の任意の値と共に(col1、col2)の別個の値が必要です。私はminやmaxのような集計関数を使うことができません。col3とcol4の値を別の行から持ってくるからです。 – Mohan

+2

col5 = 1の値を持つもう1つの列(col5)を導入することができます(col1、col2 order by col1、col2 asc)、新しい列 - col5 = 1を使用して最初の行をフィルタリングできます。 – Mohan

答えて

2

あなたが任意の行をしたい場合は、firstlastを使用しようとすることができますが、それははるかにきれいからであると私は真剣にスパークのアップグレードを検討します:

from pyspark.sql.functions import col, first 

df = sc.parallelize([ 
    (1, "desc1", "v1", "v3"), (2, "desc2", "v4", "v2"), 
    (1, "desc1", "v4", "v2"), (2, "desc2", "v1", "v3") 
]).toDF(["col1", "col2", "col3", "col4"]) 

keys = ["col1", "col2"] 
values = ["col3", "col4"] 
agg_exprs = [first(c).alias(c) for c in keys + ["vs_"]] 
select_exprs = keys + [ 
    "vs_.col{0} AS {1}".format(i + 1, v) for (i, v) in enumerate(values)] 

df_not_so_first = (df 
    .selectExpr("struct({}) AS vs_".format(",".join(values)), *keys) 
    .groupBy(*keys) 
    .agg(*agg_exprs) 
    .selectExpr(*select_exprs)) 

注この特定の文脈でfirstがないこと特定の行を選択すると、結果が確定的でない可能性があります。さらに、Sparkのバージョンによっては、個別の集計を個別にスケジュールすることもできます。それは

df.groupBy("col1", "col2").agg(first("col3"), first("col4")) 

col3を保証するものではありません。また、col4が同じ行から選択されることを意味します。

+0

ありがとうございました。私はfirst()関数を使って次のように試しました。それは正常に動作しています。 df.groupBy(df.col1、df.col2).agg(df.col1、df.col2、first(df.col3).alias( 'col3')、first(df.col4).alias( 'col4 '))。show() – Mohan

+1

あなたは一人で使うべきではありません。あなたが得るバージョンと設定の振る舞いによっては、確定的ではありません。 'groupBy'コンテキストでは特定の行を選択しないので、個別の集計が個別にスケジュールされている場合は、同じ行から値を取得したり、毎回同じ値を取得するという保証はありません。 – zero323

+0

私はそれを手に入れます。再度、感謝します – Mohan

関連する問題