パーティションIDを指定して、spark RDDパーティションの要素数を取得する方法はありますか?パーティション全体をスキャンせずに.
このようなもの:
Rdd.partitions().get(index).size()
スパーク用のそのようなAPIが見当たらないことを除いて。何か案は?回避策は?
ありがとう
以下は、各パーティションのサイズである要素を持つ新しいRDDを提供します。
rdd.mapPartitions(iter => Array(iter.size).iterator, true)
PySpark:
_num_partitions = 20000
a = sc.parallelize(range(int(1e6)), num_partitions)
l = a.glom().map(len).collect() # get length of each partition
print(min(l), max(l), sum(l)/len(l), len(l)) # check if skewed
_
スパーク/スカラ:
_val numPartitions = 20000
val a = sc.parallelize(0 until 1e6.toInt, numPartitions )
val l = a.glom().map(_.length).collect() # get length of each partition
print(l.min, l.max, l.sum/l.length, l.length) # check if skewed
_
RDDだけでなく、データフレームでも同じことが可能です。上記のコードにDF.rdd.glom ...を追加するだけです。
glom()
は各パーティションの要素を リストに に変換するため、メモリを大量に消費することに注意してください。メモリ使用量の少ないバージョン(pysparkバージョンのみ):
_import statistics
def get_table_partition_distribution(table_name: str):
def get_partition_len (iterator):
yield sum(1 for _ in iterator)
l = spark.table(table_name).rdd.mapPartitions(get_partition_len, True).collect() # get length of each partition
num_partitions = len(l)
min_count = min(l)
max_count = max(l)
avg_count = sum(l)/num_partitions
stddev = statistics.stdev(l)
print(f"{table_name} each of {num_partitions} partition's counts: min={min_count:,} avg±stddev={avg_count:,.1f} ±{stddev:,.1f} max={max_count:,}")
get_table_partition_distribution('someTable')
_
のようなものを出力します
someTable各1445パーティションのカウント:min = 1,201,201 avg±stddev = 1,202,811.6±21,783.4 max = 2,030,137
pzecevicの答えは機能しますが、概念的には配列を作成してからそれを反復子に変換する必要はありません。イテレータを直接作成し、collect呼び出しでカウントを取得するだけです。
rdd.mapPartitions(iter => Iterator(iter.size), true).collect()
追伸Iterator.applyは引数を配列に変換する可能性が高いため、彼の答えが実際により多くの作業を行っているかどうかはわかりません。