hdfsの場所から一連のテキストファイルを読み取り、sparkを使用して繰り返しマッピングします。
JavaRDD<String> records = ctx.textFile(args[1], 1);
は、一度に1つのファイルのみを読み取ることができます。
複数のファイルを読み取り、それらを単一のRDDとして処理したい。どうやって?
hdfsの場所から一連のテキストファイルを読み取り、sparkを使用して繰り返しマッピングします。
JavaRDD<String> records = ctx.textFile(args[1], 1);
は、一度に1つのファイルのみを読み取ることができます。
複数のファイルを読み取り、それらを単一のRDDとして処理したい。どうやって?
回答:
ディレクトリ全体を指定したり、ワイルドカードを使用したり、ディレクトリとワイルドカードのCSVを使用したりすることもできます。例えば:
sc.textFile("/my/dir1,/my/paths/part-00[0-5]*,/another/dir,/a/specific/file")
Nick Chammasが指摘するように、これはHadoopの露出でFileInputFormat
あり、したがってこれはHadoop(およびScalding)でも機能します。
sc.wholeTextFiles
行で区切られていないデータに便利です
sc.textFile(multipleCommaSeparatedDirs,320)
それが19430
タスク全体ではなく合計タスクにつながると言うのは奇妙ですが、非常に低い並列処理から非常に多くのタスクが発生320
するように動作union
します
wholeTextFiles
。あなたのユースケースは何ですか?ファイルと同じ数のパーティションを使用するという条件で回避策を考えることができます...
単一のtextFile呼び出しを使用して、複数のファイルを読み取ることができます。Scala:
sc.textFile(','.join(files))
sc.textFile(files.mkString(","))
これを使えます
まず、S3パスのバッファ/リストを取得できます。
import scala.collection.JavaConverters._
import java.util.ArrayList
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.ObjectListing
import com.amazonaws.services.s3.model.S3ObjectSummary
import com.amazonaws.services.s3.model.ListObjectsRequest
def listFiles(s3_bucket:String, base_prefix : String) = {
var files = new ArrayList[String]
//S3 Client and List Object Request
var s3Client = new AmazonS3Client();
var objectListing: ObjectListing = null;
var listObjectsRequest = new ListObjectsRequest();
//Your S3 Bucket
listObjectsRequest.setBucketName(s3_bucket)
//Your Folder path or Prefix
listObjectsRequest.setPrefix(base_prefix)
//Adding s3:// to the paths and adding to a list
do {
objectListing = s3Client.listObjects(listObjectsRequest);
for (objectSummary <- objectListing.getObjectSummaries().asScala) {
files.add("s3://" + s3_bucket + "/" + objectSummary.getKey());
}
listObjectsRequest.setMarker(objectListing.getNextMarker());
} while (objectListing.isTruncated());
//Removing Base Directory Name
files.remove(0)
//Creating a Scala List for same
files.asScala
}
次に、このListオブジェクトを次のコードに渡します。注意:scはSQLContextのオブジェクトです
var df: DataFrame = null;
for (file <- files) {
val fileDf= sc.textFile(file)
if (df!= null) {
df= df.unionAll(fileDf)
} else {
df= fileDf
}
}
これで、最終的な統合RDD、つまりdfが手に入りました
オプションで、単一のBigRDDに再パーティション化することもできます
val files = sc.textFile(filename, 1).repartition(1)
再パーティション化は常に機能します:D
PySparkで、ファイルを解析するための追加の便利な方法を見つけました。おそらくScalaに同等のものがありますが、私は実用的な翻訳を思いつくのに十分満足できません。実際には、ラベルが追加されたtextFile呼び出しです(以下の例では、key =ファイル名、value =ファイルから1行です)。
「ラベル付き」textFile
入力:
import glob
from pyspark import SparkContext
SparkContext.stop(sc)
sc = SparkContext("local","example") # if running locally
sqlContext = SQLContext(sc)
for filename in glob.glob(Data_File + "/*"):
Spark_Full += sc.textFile(filename).keyBy(lambda x: filename)
出力:filename-as-keyを使用するタプルを含み、value =ファイルの各行を含む各エントリを持つ配列。(技術的には、この方法を使用すると、実際のファイルパス名の他に別のキーを使用することもできます-おそらくハッシュ表現でメモリを節約できます)。すなわち。
[('/home/folder_with_text_files/file1.txt', 'file1_contents_line1'),
('/home/folder_with_text_files/file1.txt', 'file1_contents_line2'),
('/home/folder_with_text_files/file1.txt', 'file1_contents_line3'),
('/home/folder_with_text_files/file2.txt', 'file2_contents_line1'),
...]
行のリストとして再結合することもできます。
Spark_Full.groupByKey().map(lambda x: (x[0], list(x[1]))).collect()
[('/home/folder_with_text_files/file1.txt', ['file1_contents_line1', 'file1_contents_line2','file1_contents_line3']),
('/home/folder_with_text_files/file2.txt', ['file2_contents_line1'])]
または、ファイル全体を単一の文字列に再結合します(この例では、結果はwholeTextFilesから取得したものと同じですが、文字列 "file:"がファイルパスから削除されます)。
Spark_Full.groupByKey().map(lambda x: (x[0], ' '.join(list(x[1])))).collect()
Spark_Full += sc.textFile(filename).keyBy(lambda x: filename)
、エラーが発生しましたTypeError: 'PipelinedRDD' object is not iterable
。私の理解では、その行は不変のRDDを作成するので、それを別の変数にどのように追加できるのかと思っていましたか?
あなたは使うことができます
JavaRDD<String , String> records = sc.wholeTextFiles("path of your directory")
ここでは、ファイルのパスとそのファイルのコンテンツを取得します。したがって、一度にファイル全体の任意のアクションを実行して、オーバーヘッドを節約できます
すべての答えは正しいです sc.textFile
なぜだろうと思っていたwholeTextFiles
たとえば、この場合...
val minPartitions = 2
val path = "/pathtohdfs"
sc.wholeTextFiles(path,minPartitions)
.flatMap{case (path, text)
...
1つの制限は、小さなファイルをロードする必要があることです。そうしないと、パフォーマンスが低下し、OOMにつながる可能性があります。
注意 :
さらに参照訪問
sc.wholeTextFiles(folder).flatMap...
利用可能な簡単なクリーンソリューションがあります。wholeTextFiles()メソッドを使用します。これはディレクトリを取り、キーと値のペアを形成します。返されるRDDはペアのRDDになります。以下のSpark docsの説明を見つけてください。
SparkContext.wholeTextFilesを使用すると、複数の小さなテキストファイルを含むディレクトリを読み取り、それぞれを(ファイル名、コンテンツ)のペアとして返すことができます。これは、各ファイルの行ごとに1つのレコードを返すtextFileとは対照的です
これを試して インタフェースは、外部ストレージ・システム(たとえば、ファイルシステム、キーと値の店舗など)にデータフレームを書き込むために使用されます。これにアクセスするには、DataFrame.write()を使用します。
バージョン1.4の新機能。
csv(path、mode = None、compression = None、sep = None、quote = None、escape = None、header = None、nullValue = None、escapeQuotes = None、quoteAll = None、dateFormat = None、timestampFormat = None)を保存します指定されたパスにあるCSV形式のDataFrameのコンテンツ。
パラメータ:path – Hadoopでサポートされているファイルシステムモードのパス–データがすでに存在する場合の保存操作の動作を指定します。
append:このDataFrameのコンテンツを既存のデータに追加します。overwrite:既存のデータを上書きします。ignore:データが既に存在する場合、この操作をサイレントに無視します。エラー(デフォルトの場合):データがすでに存在する場合、例外をスローします。圧縮–ファイルに保存するときに使用する圧縮コーデック。これは、大文字と小文字を区別しない既知の短縮名(none、bzip2、gzip、lz4、snappy、deflate)のいずれかです。sep –各フィールドと値の区切り文字として単一の文字を設定します。Noneが設定されている場合、デフォルト値、を使用します。quote –引用符で囲まれた値をエスケープするために使用される単一の文字を設定します。セパレーターは値の一部になります。Noneが設定されている場合は、デフォルト値の "が使用されます。引用符をオフにしたい場合は、空の文字列を設定する必要があります。escape –引用符で囲まれた値内の引用符のエスケープに使用される単一文字を設定します。Noneが設定されている場合、デフォルト値\ escapeQuotes –引用符を含む値を常に引用符で囲む必要があるかどうかを示すフラグ。Noneが設定されている場合は、デフォルト値trueを使用して、引用文字を含むすべての値をエスケープします。quoteAll –すべての値を常に引用符で囲む必要があるかどうかを示すフラグ。Noneが設定されている場合は、デフォルト値falseを使用し、引用文字を含む値のみをエスケープします。header –列の名前を最初の行として書き込みます。Noneが設定されている場合、デフォルト値のfalseが使用されます。nullValue-null値の文字列表現を設定します。Noneが設定されている場合は、デフォルト値の空の文字列が使用されます。dateFormat –日付形式を示す文字列を設定します。カスタム日付形式は、java.text.SimpleDateFormatの形式に従います。これは日付タイプに適用されます。Noneが設定されている場合、デフォルト値yyyy-MM-ddが使用されます。timestampFormat –タイムスタンプ形式を示す文字列を設定します。カスタム日付形式は、java.text.SimpleDateFormatの形式に従います。これはタイムスタンプタイプに適用されます。Noneが設定されている場合、デフォルト値yyyy-MM-dd'T'HH:mm:ss.SSSZZが使用されます。
Path
オプションがすべて適用されます。