以下の構文を使用して、monotonically_increasing_id()を使用して、行番号をpysparkデータフレームに割り当てています。
df1 = df1.withColumn("idx", monotonically_increasing_id())
現在、df1には26,572,528レコードがあります。そのため、0〜26,572,527のidx値を期待していました。
しかし、max(idx)を選択すると、その値は奇妙に大きくなります:335,008,054,165。
この機能はどうなっていますか?同じ数のレコードを持つ別のデータセットとマージするためにこの関数を使用することは信頼できますか?
単一のデータフレームに結合したい約300のデータフレームがあります。したがって、1つのデータフレームにはIDが含まれ、他のデータフレームには行に対応する異なるレコードが含まれます
ドキュメント から
単調に増加する64ビット整数を生成する列。
生成されるIDは、単調に増加し、一意であることが保証されていますが、連続的ではありません。現在の実装では、パーティションIDを上位31ビットに配置し、各パーティション内のレコード番号を下位33ビットに配置します。データフレームのパーティションは10億未満であり、各パーティションのレコードは80億未満であると仮定しています。
したがって、RDBの自動インクリメントIDとは異なり、マージに対してnot信頼性があります。
RDBのように自動インクリメント動作が必要で、データがソート可能な場合は、row_number
を使用できます
df.createOrReplaceTempView('df')
spark.sql('select row_number() over (order by "some_column") as num, * from df')
+---+-----------+
|num|some_column|
+---+-----------+
| 1| ....... |
| 2| ....... |
| 3| ..........|
+---+-----------+
データがソート可能でなく、rddsを使用してインデックスを作成してからデータフレームにフォールバックすることを気にしない場合は、rdd.zipWithIndex()
を使用できます。
例があります here
要するに:
# since you have a dataframe, use the rdd interface to create indexes with zipWithIndex()
df = df.rdd.zipWithIndex()
# return back to dataframe
df = df.toDF()
df.show()
# your data | indexes
+---------------------+---+
| _1 | _2|
+-----------=---------+---+
|[data col1,data col2]| 0|
|[data col1,data col2]| 1|
|[data col1,data col2]| 2|
+---------------------+---+
データフレームを必要なものにするには、その後、さらにいくつかの変換が必要になるでしょう。注:非常にパフォーマンスの高いソリューションではありません。
お役に立てれば。幸運を!
編集:考えてみると、monotonically_increasing_id
を組み合わせてrow_number
を使用できます:
# create a monotonically increasing id
df = df.withColumn("idx", monotonically_increasing_id())
# then since the id is increasing but not consecutive, it means you can sort by it, so you can use the `row_number`
df.createOrReplaceTempView('df')
new_df = spark.sql('select row_number() over (order by "idx") as num, * from df')
ただし、パフォーマンスについてはわかりません。
aPI関数を使用すると、次のように簡単に実行できます
from pyspark.sql.window import Window as W
from pyspark.sql import functions as F
df1 = df1.withColumn("idx", F.monotonically_increasing_id())
windowSpec = W.orderBy("idx")
df1.withColumn("idx", F.row_number().over(windowSpec)).show()
答えがお役に立てば幸いです
@mkaranによる解決策が有用であることがわかりましたが、私にとっては、ウィンドウ関数の使用中に順序付け列はありませんでした。データフレームの行の順序をインデックスとして維持したかった(pandasデータフレームに表示されるもの)。したがって、編集セクションのソリューションが使用されました。これは優れたソリューションなので(パフォーマンスが問題にならない場合)、別の回答として共有したいと思います。
# Add a increasing data column
df_index = df.withColumn("idx", monotonically_increasing_id())
# Create the window specification
w = Window.orderBy("idx")
# Use row number with the window specification
df_index = df_index.withColumn("index", F.row_number().over(w))
# Drop the created increasing data column
df2_index = df2_index.drop("idx")
df
は元のデータフレームであり、df_index
は新しいデータフレームです。