pyspark および spark-dataframe タグを使用していくつかの質問を読むのにかなりの時間を費やしてきましたが、非常に頻繁にポスターから十分な情報が得られないことがわかりました彼らの質問を本当に理解します。私は通常、彼らに [〜#〜] mcve [〜#〜] を投稿するようにコメントしますが、サンプルの入出力データを見せるようにすることは、歯を引っ張るようなものです。例: this question のコメントを参照してください。
おそらく問題の一部は、spark-dataframesのMCVEを簡単に作成する方法を知らないことです。リンクできるガイドとして、spark-dataframeバージョンの this pandas question があると便利だと思います。
それでは、どのようにして、良い、再現可能な例を作成するのでしょうか?
少なくとも、ポスターは、データフレームとコードを簡単に作成するために使用できるコードの行と列を提供する必要があります。簡単に言うと、カットアンドペーストを意味します。問題を実証するために、できるだけ小さくしてください。
次のデータフレームがあります:
+-----+---+-----+----------+
|index| X|label| date|
+-----+---+-----+----------+
| 1| 1| A|2017-01-01|
| 2| 3| B|2017-01-02|
| 3| 5| A|2017-01-03|
| 4| 7| B|2017-01-04|
+-----+---+-----+----------+
このコードで作成できます:
df = sqlCtx.createDataFrame(
[
(1, 1, 'A', '2017-01-01'),
(2, 3, 'B', '2017-01-02'),
(3, 5, 'A', '2017-01-03'),
(4, 7, 'B', '2017-01-04')
],
('index', 'X', 'label', 'date')
)
特定の質問をして、希望する出力を表示してください。
新しい列を作成する方法'is_divisible'
値を持つ'yes'
月の日付の場合'date'
プラス7日間は列の値で割り切れる'X'
、and'no'
それ以外の場合?
望ましい出力:
+-----+---+-----+----------+------------+
|index| X|label| date|is_divisible|
+-----+---+-----+----------+------------+
| 1| 1| A|2017-01-01| yes|
| 2| 3| B|2017-01-02| yes|
| 3| 5| A|2017-01-03| yes|
| 4| 7| B|2017-01-04| no|
+-----+---+-----+----------+------------+
希望する出力を得る方法を詳細に説明してください。計算例を示すのに役立ちます。
たとえば、行1の場合、X = 1および日付= 2017-01-01。日付に7日を追加すると、2017-01-08になります。月の日は8です。8は1で割り切れるので、答えは「はい」です。
同様に、最後の行X = 7および日付= 2017-01-04。日付に7を追加すると、月の日として11が得られます。 11%7は0ではないため、答えは「いいえ」です。
コードが機能しない場合でも、コードのall *を含めて、実行または試行した内容を表示します。行き詰まっている場所を教えてください。エラーが発生した場合は、エラーメッセージを含めてください。
(*コードを省略してsparkコンテキストを作成できますが、すべてのインポートを含める必要があります。)
新しい列を追加する方法は知っていますdate
プラス7日間ですが、月の日を整数として取得するのに問題があります。
from pyspark.sql import functions as f
df.withColumn("next_week", f.date_add("date", 7))
質問がパフォーマンスチューニングに関連している場合は、次の情報を含めてください。
拡張実行計画を含めるのが最適です。 Pythonの場合:
df.explain(True)
Scalaの場合:
df.explain(true)
または統計付きの拡張実行計画。 Pythonの場合:
print(df._jdf.queryExecution().stringWithStats())
scalaの場合:
df.queryExecution.stringWithStats
mode
-local
、client
、 `cluster。slowは相対的です。特に、非分散アプリケーションを移植する場合、または低遅延が予想される場合は重要です。さまざまなタスクとステージの正確なタイミングは、Spark UI(sc.uiWebUrl
)jobs
またはSpark=REST UI。
各コンテキストに確立された名前を使用すると、問題をすばやく再現できます。
sc
-SparkContext
の場合。sqlContext
-SQLContext
の場合。spark
-SparkSession
の場合。強力な型推論はScalaの最も便利な機能の1つですが、コンテキストから取り出されたコードを分析するのが難しくなります。型がコンテキストから明らかな場合でも、変数に注釈を付ける方が適切です。好む
val lines: RDD[String] = sc.textFile("path")
val words: RDD[String] = lines.flatMap(_.split(" "))
以上
val lines = sc.textFile("path")
val words = lines.flatMap(_.split(" "))
一般的に使用されるツールはあなたを助けることができます:
spark-Shell
/Scala Shell
つかいます :t
scala> val rdd = sc.textFile("README.md")
rdd: org.Apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[1] at textFile at <console>:24
scala> :t rdd
org.Apache.spark.rdd.RDD[String]
InteliJのアイデア
つかいます Alt + =
質疑応答;追加の提案:
Sparkはまだ進化していますが、1.xの頃ほど急速ではありません。作業中のバージョンを含めることは常に(ただし、多少古いバージョンを使用している場合は特に)良いアイデアです。個人的に、私はいつもanswersを次のように開始します:
spark.version
# u'2.2.0'
または
sc.version
# u'2.2.0'
Pythonバージョンも含めることは、決して悪い考えではありません。
質問が厳密にSpark= SQLおよびデータフレームに関するものではない場合、たとえば、何らかの機械学習操作でデータフレームを使用する場合は、インポートについて明示してください- この質問 を参照してください=、ここで(現在削除された)コメントの広範な交換の後にのみインポートがOPに追加されました(これらの誤ったインポートが問題の根本原因であることが判明しました)。
なぜこれが必要なのですか?たとえば、このLDA
from pyspark.mllib.clustering import LDA
このLDAとはdifferent:
from pyspark.ml.clustering import LDA
最初は古いRDDベースのAPI(以前のSpark MLlib)からのもので、2番目は新しいデータフレームベースのAPI(Spark ML)からのものです。
OK、これは主観的であると告白します。PySparkの質問には、デフォルトでpython
のタグを付けるべきではないと思います;問題は、python
タグが自動的にコードの強調表示を行うことです(そして、これがPySparkの質問に使用する主な理由だと思います)。とにかく、あなたがたまたま同意して、それでもニースの強調表示されたコードが欲しいなら、単に関連するマークダウンディレクティブを含めてください:
<!-- language-all: lang-python -->
投稿のどこか、最初のコードスニペットの前。
[更新: 要求しましたpyspark
およびsparkr
タグの自動構文強調表示-歓迎します]
この小さなヘルパー関数は、Spark DataFrameへの出力ファイルの解析に役立ちます。
PySpark:
from pyspark.sql.functions import *
def read_spark_output(file_path):
step1 = spark.read \
.option("header","true") \
.option("inferSchema","true") \
.option("delimiter","|") \
.option("parserLib","UNIVOCITY") \
.option("ignoreLeadingWhiteSpace","true") \
.option("ignoreTrailingWhiteSpace","true") \
.option("comment","+") \
.csv("file://{}".format(file_path))
# select not-null columns
step2 = t.select([c for c in t.columns if not c.startswith("_")])
# deal with 'null' string in column
return step2.select(*[when(~col(col_name).eqNullSafe("null"), col(col_name)).alias(col_name) for col_name in step2.columns])
スカラ:
// read Spark Output Fixed width table:
def readSparkOutput(filePath: String): org.Apache.spark.sql.DataFrame = {
val step1 = spark.read
.option("header", "true")
.option("inferSchema", "true")
.option("delimiter", "|")
.option("parserLib", "UNIVOCITY")
.option("ignoreLeadingWhiteSpace", "true")
.option("ignoreTrailingWhiteSpace", "true")
.option("comment", "+")
.csv(filePath)
val step2 = step1.select(step1.columns.filterNot(_.startsWith("_c")).map(step1(_)): _*)
val columns = step2.columns
columns.foldLeft(step2)((acc, c) => acc.withColumn(c, when(col(c) =!= "null", col(c))))
}
使用法:
df = read_spark_output("file:///tmp/spark.out")
PS:pysparkの場合、eqNullSafe
はspark 2.3
。