例えば
sqlContext = SQLContext(sc)
sample=sqlContext.sql("select Name ,age ,city from user")
sample.show()
上記のステートメントは端末上でテーブル全体を印刷しますが、forまたはwhileを使用してそのテーブルの各行にアクセスし、さらに計算を実行します。
Sparkの並列計算フレームワークを「ループ」して活用するには、カスタム関数を定義してマップを使用できます。
def customFunction(row):
return (row.name, row.age, row.city)
sample2 = sample.rdd.map(customFunction)
または
sample2 = sample.rdd.map(lambda x: (x.name, x.age, x.city))
カスタム関数は、データフレームのすべての行に適用されます。 sample2はRDD
であり、データフレームではないことに注意してください。
より複雑な計算を実行する場合は、マップが必要になる場合があります。単純な派生列を追加するだけの場合は、データフレームを返すwithColumn
を使用できます。
sample3 = sample.withColumn('age2', sample.age + 2)
単純にできません。 DataFrames
は、他の分散データ構造と同じですが、 反復可能 ではなく、専用の高階関数および/またはSQLメソッドのみを使用してアクセスできます。
もちろんcollect
for row in df.rdd.collect():
do_something(row)
またはtoLocalIterator
を変換します
for row in df.rdd.toLocalIterator():
do_something(row)
上記のようにローカルで反復しますが、Sparkを使用するすべての目的に勝ります。
Pythonでリスト内包表記を使用すると、2行だけを使用して値の列全体をリストに収集できます。
df = sqlContext.sql("show tables in default")
tableList = [x["tableName"] for x in df.rdd.collect()]
上記の例では、データベース 'default'のテーブルのリストを返しますが、sql()で使用されるクエリを置き換えることで同じものを適合させることができます。
またはもっと短縮されます:
tableList = [x["tableName"] for x in sqlContext.sql("show tables in default").rdd.collect()]
また、3つの列の例では、辞書のリストを作成し、forループでそれらを反復処理できます。
sql_text = "select name, age, city from user"
tupleList = [{name:x["name"], age:x["age"], city:x["city"]}
for x in sqlContext.sql(sql_text).rdd.collect()]
for row in tupleList:
print("{} is a {} year old from {}".format(
row["name"],
row["age"],
row["city"]))
DataFrameオブジェクトの各行に対して何かを実行する場合は、map
を使用します。これにより、各行でさらに計算を実行できます。これは、0
からlen(dataset)-1
にデータセット全体をループすることと同等です。
これは、DataFrameではなくPipelinedRDDを返すことに注意してください。
result = spark.createDataFrame([('SpeciesId','int'), ('SpeciesName','string')],["col_name", "data_type"]);
for f in result.collect():
print (f.col_name)
上
tupleList = [{name:x["name"], age:x["age"], city:x["city"]}
あるべき
tupleList = [{'name':x["name"], 'age':x["age"], 'city':x["city"]}
name
、age
、およびcity
は変数ではなく、単に辞書のキーです。