Dapatkah seseorang menjelaskan kepada saya perbedaan antara peta dan flatMap dan apa gunanya kasus yang baik untuk masing-masing?
Apa yang dimaksud dengan "meratakan hasil"? Apa gunanya?
Dapatkah seseorang menjelaskan kepada saya perbedaan antara peta dan flatMap dan apa gunanya kasus yang baik untuk masing-masing?
Apa yang dimaksud dengan "meratakan hasil"? Apa gunanya?
Jawaban:
Berikut adalah contoh perbedaannya, sebagai spark-shell
sesi:
Pertama, beberapa data - dua baris teks:
val rdd = sc.parallelize(Seq("Roses are red", "Violets are blue")) // lines
rdd.collect
res0: Array[String] = Array("Roses are red", "Violets are blue")
Sekarang, map
mengubah RDD panjang N menjadi RDD panjang N.
Misalnya, memetakan dari dua garis menjadi dua panjang garis:
rdd.map(_.length).collect
res1: Array[Int] = Array(13, 16)
Tetapi flatMap
(secara longgar) mengubah RDD dengan panjang N menjadi koleksi koleksi N, kemudian meratakannya menjadi RDD tunggal hasil.
rdd.flatMap(_.split(" ")).collect
res2: Array[String] = Array("Roses", "are", "red", "Violets", "are", "blue")
Kami memiliki beberapa kata per baris, dan beberapa baris, tetapi kami berakhir dengan satu array output kata
Hanya untuk menggambarkan itu, pemetaan datar dari kumpulan garis ke kumpulan kata-kata terlihat seperti:
["aa bb cc", "", "dd"] => [["aa","bb","cc"],[],["dd"]] => ["aa","bb","cc","dd"]
Oleh karena itu, RDD input dan output biasanya memiliki ukuran yang berbeda untuk flatMap
.
Jika kami mencoba menggunakan map
dengan split
fungsi kami , kami akan berakhir dengan struktur bersarang (RDD array kata, dengan tipe RDD[Array[String]]
) karena kami harus memiliki satu hasil per input:
rdd.map(_.split(" ")).collect
res3: Array[Array[String]] = Array(
Array(Roses, are, red),
Array(Violets, are, blue)
)
Akhirnya, satu kasus khusus yang berguna adalah pemetaan dengan fungsi yang mungkin tidak mengembalikan jawaban, dan karenanya mengembalikan sebuah Option
. Kita dapat menggunakan flatMap
untuk memfilter elemen yang mengembalikan None
dan mengekstrak nilai dari yang mengembalikan Some
:
val rdd = sc.parallelize(Seq(1,2,3,4))
def myfn(x: Int): Option[Int] = if (x <= 2) Some(x * 10) else None
rdd.flatMap(myfn).collect
res3: Array[Int] = Array(10,20)
(mencatat di sini bahwa Opsi berperilaku lebih seperti daftar yang memiliki satu elemen, atau elemen nol)
["a b c", "", "d"] => [["a","b","c"],[],["d"]]
?
split
atas daftar Strings akan menghasilkan Daftar Array)
Secara umum kami menggunakan contoh jumlah kata dalam hadoop. Saya akan menggunakan use case yang sama dan akan menggunakan map
danflatMap
dan kita akan melihat perbedaan bagaimana memproses data.
Di bawah ini adalah file data sampel.
hadoop is fast
hive is sql on hdfs
spark is superfast
spark is awesome
File di atas akan diuraikan menggunakan map
dan flatMap
.
map
>>> wc = data.map(lambda line:line.split(" "));
>>> wc.collect()
[u'hadoop is fast', u'hive is sql on hdfs', u'spark is superfast', u'spark is awesome']
Input memiliki 4 baris dan ukuran output adalah 4 juga, yaitu, elemen N ==> elemen N.
flatMap
>>> fm = data.flatMap(lambda line:line.split(" "));
>>> fm.collect()
[u'hadoop', u'is', u'fast', u'hive', u'is', u'sql', u'on', u'hdfs', u'spark', u'is', u'superfast', u'spark', u'is', u'awesome']
Outputnya berbeda dari peta.
Mari kita menetapkan 1 sebagai nilai untuk setiap kunci untuk mendapatkan jumlah kata.
fm
: RDD dibuat dengan menggunakan flatMap
wc
: RDD dibuat menggunakan map
>>> fm.map(lambda word : (word,1)).collect()
[(u'hadoop', 1), (u'is', 1), (u'fast', 1), (u'hive', 1), (u'is', 1), (u'sql', 1), (u'on', 1), (u'hdfs', 1), (u'spark', 1), (u'is', 1), (u'superfast', 1), (u'spark', 1), (u'is', 1), (u'awesome', 1)]
Sedangkan flatMap
pada RDD wc
akan memberikan output yang tidak diinginkan di bawah ini:
>>> wc.flatMap(lambda word : (word,1)).collect()
[[u'hadoop', u'is', u'fast'], 1, [u'hive', u'is', u'sql', u'on', u'hdfs'], 1, [u'spark', u'is', u'superfast'], 1, [u'spark', u'is', u'awesome'], 1]
Anda tidak bisa mendapatkan jumlah kata jika map
digunakan alih-alih flatMap
.
Sesuai definisi, perbedaan antara map
dan flatMap
adalah:
map
: Ini mengembalikan RDD baru dengan menerapkan fungsi yang diberikan ke setiap elemen RDD. Berfungsi dalammap
mengembalikan hanya satu item.
flatMap
: Mirip denganmap
, ia mengembalikan RDD baru dengan menerapkan fungsi ke setiap elemen RDD, tetapi output diratakan.
.map(lambda line:line.split(" "))
bukan array string. Anda harus mengubah data.collect()
ke wc.collect
dan Anda akan melihat array array.
wc.collect()
?
Jika Anda menanyakan perbedaan antara RDD.map dan RDD.flatMap di Spark, peta mengubah RDD ukuran N ke yang lain dari ukuran N. misalnya.
myRDD.map(x => x*2)
misalnya, jika myRDD terdiri dari Doubles.
Sementara flatMap dapat mengubah RDD menjadi antera dengan ukuran berbeda: mis .:
myRDD.flatMap(x =>new Seq(2*x,3*x))
yang akan mengembalikan RDD ukuran 2 * N atau
myRDD.flatMap(x =>if x<10 new Seq(2*x,3*x) else new Seq(x) )
Itu bermuara pada pertanyaan awal Anda: apa yang Anda maksud dengan meratakan ?
Saat Anda menggunakan flatMap, koleksi "multi dimensi" menjadi koleksi "satu dimensi" .
val array1d = Array ("1,2,3", "4,5,6", "7,8,9")
//array1d is an array of strings
val array2d = array1d.map(x => x.split(","))
//array2d will be : Array( Array(1,2,3), Array(4,5,6), Array(7,8,9) )
val flatArray = array1d.flatMap(x => x.split(","))
//flatArray will be : Array (1,2,3,4,5,6,7,8,9)
Anda ingin menggunakan flatMap ketika,
Gunakan test.md
sebagai contoh:
➜ spark-1.6.1 cat test.md
This is the first line;
This is the second line;
This is the last line.
scala> val textFile = sc.textFile("test.md")
scala> textFile.map(line => line.split(" ")).count()
res2: Long = 3
scala> textFile.flatMap(line => line.split(" ")).count()
res3: Long = 15
scala> textFile.map(line => line.split(" ")).collect()
res0: Array[Array[String]] = Array(Array(This, is, the, first, line;), Array(This, is, the, second, line;), Array(This, is, the, last, line.))
scala> textFile.flatMap(line => line.split(" ")).collect()
res1: Array[String] = Array(This, is, the, first, line;, This, is, the, second, line;, This, is, the, last, line.)
Jika Anda menggunakan map
metode, Anda akan mendapatkan garis test.md
, untuk flatMap
metode, Anda akan mendapatkan jumlah kata.
The map
Metode ini mirip dengan flatMap
, mereka semua kembali sebuah RDD baru. map
Metode sering menggunakan mengembalikan RDD baru, flatMap
metode sering menggunakan kata-kata split.
map
mengembalikan RDD dengan jumlah elemen yang sama flatMap
mungkin tidak.
Contoh kasus penggunaan untukflatMap
Menyaring data yang hilang atau salah.
Contoh use case untukmap
Use dalam berbagai kasus dimana jumlah elemen input dan outputnya sama.
number.csv
1
2
3
-
4
-
5
map.py menambahkan semua angka di add.csv.
from operator import *
def f(row):
try:
return float(row)
except Exception:
return 0
rdd = sc.textFile('a.csv').map(f)
print(rdd.count()) # 7
print(rdd.reduce(add)) # 15.0
flatMap.py digunakan flatMap
untuk menyaring data yang hilang sebelum penambahan. Jumlah yang lebih sedikit ditambahkan dibandingkan dengan versi sebelumnya.
from operator import *
def f(row):
try:
return [float(row)]
except Exception:
return []
rdd = sc.textFile('a.csv').flatMap(f)
print(rdd.count()) # 5
print(rdd.reduce(add)) # 15.0
peta dan flatMap serupa, dalam arti mereka mengambil garis dari RDD input dan menerapkan fungsi di atasnya. Perbedaannya adalah bahwa fungsi di peta hanya mengembalikan satu elemen, sedangkan fungsi di flatMap dapat mengembalikan daftar elemen (0 atau lebih) sebagai iterator.
Juga, output dari flatMap diratakan. Meskipun fungsi dalam flatMap mengembalikan daftar elemen, flatMap mengembalikan RDD yang memiliki semua elemen dari daftar dengan cara datar (bukan daftar).
semua contoh baik .... Berikut ini adalah ilustrasi visual yang bagus ... sumber sumber: Pelatihan dataFlair percikan
Peta: Peta adalah operasi transformasi di Apache Spark. Ini berlaku untuk setiap elemen RDD dan mengembalikan hasilnya sebagai RDD baru. Di Peta, pengembang operasi dapat menentukan logika bisnis kustomnya sendiri. Logika yang sama akan diterapkan ke semua elemen RDD.
map
Fungsi Spark RDD mengambil satu elemen sebagai input, memprosesnya sesuai dengan kode khusus (ditentukan oleh pengembang) dan mengembalikan satu elemen sekaligus. Peta mentransformasikan RDD dengan panjang N menjadi RDD dengan panjang lain dari N. RDD input dan output biasanya akan memiliki jumlah catatan yang sama.
Contoh map
menggunakan scala:
val x = spark.sparkContext.parallelize(List("spark", "map", "example", "sample", "example"), 3)
val y = x.map(x => (x, 1))
y.collect
// res0: Array[(String, Int)] =
// Array((spark,1), (map,1), (example,1), (sample,1), (example,1))
// rdd y can be re writen with shorter syntax in scala as
val y = x.map((_, 1))
y.collect
// res1: Array[(String, Int)] =
// Array((spark,1), (map,1), (example,1), (sample,1), (example,1))
// Another example of making tuple with string and it's length
val y = x.map(x => (x, x.length))
y.collect
// res3: Array[(String, Int)] =
// Array((spark,5), (map,3), (example,7), (sample,6), (example,7))
FlatMap:
A flatMap
adalah operasi transformasi. Ini berlaku untuk setiap elemen RDD dan mengembalikan hasilnya seperti baru RDD
. Ini mirip dengan Peta, tetapi FlatMap memungkinkan pengembalian 0, 1 atau lebih elemen dari fungsi peta. Dalam operasi FlatMap, pengembang dapat menentukan logika bisnis kustomnya sendiri. Logika yang sama akan diterapkan ke semua elemen RDD.
Apa yang dimaksud dengan "meratakan hasil"?
Fungsi FlatMap mengambil satu elemen sebagai input, memprosesnya sesuai dengan kode khusus (ditentukan oleh pengembang) dan mengembalikan 0 elemen atau lebih sekaligus. flatMap
() mengubah RDD dengan panjang N menjadi RDD dengan panjang M.
Contoh flatMap
menggunakan scala:
val x = spark.sparkContext.parallelize(List("spark flatmap example", "sample example"), 2)
// map operation will return Array of Arrays in following case : check type of res0
val y = x.map(x => x.split(" ")) // split(" ") returns an array of words
y.collect
// res0: Array[Array[String]] =
// Array(Array(spark, flatmap, example), Array(sample, example))
// flatMap operation will return Array of words in following case : Check type of res1
val y = x.flatMap(x => x.split(" "))
y.collect
//res1: Array[String] =
// Array(spark, flatmap, example, sample, example)
// RDD y can be re written with shorter syntax in scala as
val y = x.flatMap(_.split(" "))
y.collect
//res2: Array[String] =
// Array(spark, flatmap, example, sample, example)
Perbedaannya dapat dilihat dari contoh kode pyspark di bawah ini:
rdd = sc.parallelize([2, 3, 4])
rdd.flatMap(lambda x: range(1, x)).collect()
Output:
[1, 1, 2, 1, 2, 3]
rdd.map(lambda x: range(1, x)).collect()
Output:
[[1], [1, 2], [1, 2, 3]]
Flatmap dan Map, keduanya mengubah koleksi.
Perbedaan:
map (func)
Mengembalikan dataset terdistribusi baru yang dibentuk dengan melewatkan setiap elemen dari sumber melalui sebuah fungsi func.
flatMap (func)
Mirip dengan peta, tetapi setiap item input dapat dipetakan ke 0 atau lebih item output (jadi func harus mengembalikan Seq daripada satu item).
Fungsi transformasi:
peta : Satu elemen dalam -> satu elemen keluar.
flatMap : Satu elemen dalam -> 0 elemen atau lebih keluar (koleksi).
RDD.map
mengembalikan semua elemen dalam array tunggal
RDD.flatMap
mengembalikan elemen dalam array array
mari kita asumsikan kita memiliki teks dalam file text.txt sebagai
Spark is an expressive framework
This text is to understand map and faltMap functions of Spark RDD
Menggunakan peta
val text=sc.textFile("text.txt").map(_.split(" ")).collect
keluaran:
text: **Array[Array[String]]** = Array(Array(Spark, is, an, expressive, framework), Array(This, text, is, to, understand, map, and, faltMap, functions, of, Spark, RDD))
Menggunakan flatMap
val text=sc.textFile("text.txt").flatMap(_.split(" ")).collect
keluaran:
text: **Array[String]** = Array(Spark, is, an, expressive, framework, This, text, is, to, understand, map, and, faltMap, functions, of, Spark, RDD)
Untuk semua yang menginginkan PySpark terkait:
Contoh transformasi: flatMap
>>> a="hello what are you doing"
>>> a.split()
['Halo apa yang kamu lakukan']
>>> b=["hello what are you doing","this is rak"]
>>> b.split()
Traceback (panggilan terakhir terakhir): File "", line 1, di AttributeError: objek 'list' tidak memiliki atribut 'split'
>>> rline=sc.parallelize(b)
>>> type(rline)
>>> def fwords(x):
... return x.split()
>>> rword=rline.map(fwords)
>>> rword.collect()
[['hello', 'what', 'are', 'you', 'doing'], ['this', 'is', 'rak']]
>>> rwordflat=rline.flatMap(fwords)
>>> rwordflat.collect()
['hello', 'what', 'are', 'you', 'doing', 'this', 'is', 'rak']
Semoga bermanfaat :)
map
: Ini mengembalikan yang baru RDD
dengan menerapkan fungsi ke setiap elemen RDD
. Fungsi dalam .map hanya dapat mengembalikan satu item.
flatMap
: Mirip dengan peta, ia mengembalikan yang baru RDD
dengan menerapkan fungsi ke setiap elemen RDD, tetapi hasilnya rata.
Juga, fungsi dalam flatMap
dapat mengembalikan daftar elemen (0 atau lebih)
Sebagai contoh:
sc.parallelize([3,4,5]).map(lambda x: range(1,x)).collect()
Output: [[1, 2], [1, 2, 3], [1, 2, 3, 4]]
sc.parallelize([3,4,5]).flatMap(lambda x: range(1,x)).collect()
Keluaran: pemberitahuan o / p diratakan dalam satu daftar [1, 2, 1, 2, 3, 1, 2, 3, 4]
Sumber: https://www.linkedin.com/pulse/difference-between-map-flatmap-transformations-spark-pyspark-pandey/
peta:
adalah metode tingkat tinggi yang mengambil fungsi sebagai input dan menerapkannya ke setiap elemen dalam RDD sumber.
flatMap:
metode tingkat tinggi dan operasi transformasi yang mengambil fungsi input.
Perbedaan dalam output peta dan flatMap:
1.flatMap
val a = sc.parallelize(1 to 10, 5)
a.flatMap(1 to _).collect()
Keluaran:
1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
2 map
.:
val a = sc.parallelize(List("dog", "salmon", "salmon", "rat", "elephant"), 3)
val b = a.map(_.length).collect()
Keluaran:
3 6 6 3 8
sementara
RDD.map
danRDD.flatMap
di Apache Spark . Secara umum, operasi RDD Spark dimodelkan setelah operasi pengumpulan Scala yang sesuai. Jawaban di stackoverflow.com/q/1059776/590203 , yang membahas perbedaan antaramap
danflatMap
di Scala, mungkin bermanfaat bagi Anda.