Birisi bana harita ve flatMap arasındaki farkı açıklayabilir ve her biri için iyi bir kullanım durumu nedir?
"Sonuçları düzleştir" ne anlama geliyor? Bu ne için iyi?
Birisi bana harita ve flatMap arasındaki farkı açıklayabilir ve her biri için iyi bir kullanım durumu nedir?
"Sonuçları düzleştir" ne anlama geliyor? Bu ne için iyi?
Yanıtlar:
İşte bir spark-shell
oturum olarak farkın bir örneği :
İlk olarak, bazı veriler - iki metin satırı:
val rdd = sc.parallelize(Seq("Roses are red", "Violets are blue")) // lines
rdd.collect
res0: Array[String] = Array("Roses are red", "Violets are blue")
Şimdi, map
N uzunluğundaki bir RDD'yi N uzunluğundaki başka bir RDD'ye dönüştürür.
Örneğin, iki satırdan iki satır uzunluğuna eşler:
rdd.map(_.length).collect
res1: Array[Int] = Array(13, 16)
Ancak flatMap
(gevşekçe), N uzunluğunda bir RDD'yi N koleksiyonuna dönüştürür, sonra bunları tek bir RDD sonuçlarına düzleştirir.
rdd.flatMap(_.split(" ")).collect
res2: Array[String] = Array("Roses", "are", "red", "Violets", "are", "blue")
Her satırda birden çok kelime ve birden çok satır var, ancak sonuçta tek bir çıktı dizisi elde ediyoruz
Bunu açıklamak için, bir satır koleksiyonundan bir kelime koleksiyonuna geçmek şu şekildedir:
["aa bb cc", "", "dd"] => [["aa","bb","cc"],[],["dd"]] => ["aa","bb","cc","dd"]
Bu nedenle giriş ve çıkış RDD'leri tipik olarak farklı boyutlarda olacaktır flatMap
.
Kullandığımız çalıştı olsaydı map
bizim ile split
fonksiyonu, biz iç içe yapılar (tip kelimelerin diziler RDD ile sona erdi olurdu RDD[Array[String]]
biz girdi başına tam olarak bir sonuç olması gerekir çünkü):
rdd.map(_.split(" ")).collect
res3: Array[Array[String]] = Array(
Array(Roses, are, red),
Array(Violets, are, blue)
)
Son olarak, kullanışlı bir özel durum, bir yanıtı döndürmeyebilecek bir işlevle eşleştirmektir ve bu nedenle bir Option
. Biz kullanabilirsiniz flatMap
o dönüş elemanları filtrelemek için None
bir dönüş olanlar değerleri ve ayıklamak 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)
(burada bir Seçeneğin bir öğe veya sıfır öğe içeren bir liste gibi davranacağına dikkat edin)
["a b c", "", "d"] => [["a","b","c"],[],["d"]]
mi?
split
bir Dizeler listesi eşlemek Dizilerin Listesi üretecektir)
Genellikle hadoop'ta kelime sayısı örneğini kullanırız. Aynı kullanım durumunu alacağım ve kullanacağım map
ve flatMap
verileri nasıl işlediğini göreceğiz.
Örnek veri dosyası aşağıdadır.
hadoop is fast
hive is sql on hdfs
spark is superfast
spark is awesome
Yukarıdaki dosya map
ve ile ayrıştırılacaktır 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']
Girdinin 4 satırı vardır ve çıktı boyutu da 4'tür, yani N öğeleri ==> N öğeleri.
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']
Çıktı haritadan farklı.
Kelime sayısını elde etmek için her tuş için 1 değerini atayalım.
fm
: RDD kullanılarak oluşturuldu flatMap
wc
: RDD kullanılarak oluşturuldu 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)]
Oysa flatMap
RDD üzerinde wc
istenmeyen çıkış altında verir:
>>> 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]
Bunun map
yerine kullanılırsa kelime sayısını alamazsınız flatMap
.
Tanıma göre map
ve arasındaki fark flatMap
:
map
: RDD'nin her öğesine verilen işlevi uygulayarak yeni bir RDD döndürür. İçindeki işlevmap
yalnızca bir öğe döndürür.
flatMap
: Benzer şekildemap
, RDD'nin her öğesine bir işlev uygulayarak yeni bir RDD döndürür, ancak çıktı düzleştirilir.
.map(lambda line:line.split(" "))
dizelerden oluşan bir dizi değil. Sen değişmelidir data.collect()
için wc.collect
ve diziler içeren bir dizi göreceksiniz.
wc.collect()
mu
Spark'da RDD.map ve RDD.flatMap arasındaki farkı soruyorsanız, harita N boyutundaki bir RDD'yi N boyutundaki başka bir RDD'ye dönüştürür. Örneğin.
myRDD.map(x => x*2)
örneğin, myRDD, Çiftler'den oluşuyorsa.
FlatMap, RDD'yi farklı boyuttaki bir taneye dönüştürebilir:
myRDD.flatMap(x =>new Seq(2*x,3*x))
2 * N boyutunda bir RDD döndürecek veya
myRDD.flatMap(x =>if x<10 new Seq(2*x,3*x) else new Seq(x) )
İlk sorunuza kaynar: düzleştirmekle ne demek istiyorsun ?
FlatMap kullandığınızda, "çok boyutlu" bir koleksiyon "tek boyutlu" bir koleksiyon haline gelir .
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)
Aşağıdaki durumlarda flatMap kullanmak istiyorsunuz,
test.md
Örnek olarak kullanın :
➜ 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.)
map
Metod kullanırsanız, metod test.md
için flatMap
kelime sayısını alırsınız.
map
Yöntem benzer flatMap
, hepsi dönüş yeni RDD vardır. map
yöntem genellikle yeni bir RDD döndürmek için flatMap
yöntem, genellikle bölünmüş sözcükleri kullanmak için yöntem.
map
eşit flatMap
olmasa da eşit sayıda öğenin RDD değerini döndürür .
flatMap
Eksik veya yanlış verileri filtrelemek için örnek bir kullanım örneği .
map
Giriş ve çıkış elemanlarının sayısının aynı olduğu çok çeşitli durumlarda Kullanım için örnek bir kullanım örneği .
number.csv
1
2
3
-
4
-
5
map.py tüm numaraları add.csv dosyasına ekler.
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 kullanırflatMap
ilave edilmeden önce eksik verilere filtre için. Önceki sürüme kıyasla daha az sayı eklenir.
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
map ve flatMap benzerdir, yani RDD girişinden bir çizgi alırlar ve üzerine bir işlev uygularlar. Farklı olmaları, haritadaki işlevin yalnızca bir öğe döndürmesidir; flatMap'teki işlev ise yineleyici olarak bir öğe listesi (0 veya daha fazla) döndürebilir.
Ayrıca, flatMap'in çıktısı düzleştirilir. FlatMap içindeki işlev bir öğe listesi döndürse de, flatMap listeden tüm öğeleri düz bir şekilde içeren (bir liste değil) bir RDD döndürür.
tüm örnekler iyi .... İşte güzel görsel illüstrasyon ... kaynak nezaket: Spark kıvılcım DataFlair eğitimi
Harita: Harita, Apache Spark'daki bir dönüşüm işlemidir. RDD'nin her bir öğesi için geçerlidir ve sonucu yeni RDD olarak döndürür. Harita'da, operasyon geliştiricisi kendi özel iş mantığını tanımlayabilir. Aynı mantık RDD'nin tüm elemanlarına uygulanacaktır.
Spark RDD map
işlevi, bir öğeyi özel koda (geliştirici tarafından belirtilir) göre girdi işlemi olarak alır ve her defasında bir öğe döndürür. Harita, N uzunluğundaki bir RDD'yi N uzunluğundaki başka bir RDD'ye dönüştürür. Giriş ve çıkış RDD'leri tipik olarak aynı sayıda kayda sahip olacaktır.
map
Scala kullanımına örnek :
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))
Düz harita :
A flatMap
bir dönüşüm işlemidir. RDD'nin her bir öğesi için geçerlidir ve sonucu yeni olarak döndürür RDD
. Harita'ya benzer, ancak FlatMap harita işlevinden 0, 1 veya daha fazla öğenin döndürülmesine izin verir. FlatMap işleminde, bir geliştirici kendi özel iş mantığını tanımlayabilir. Aynı mantık RDD'nin tüm elemanlarına uygulanacaktır.
"Sonuçları düzleştir" ne anlama geliyor?
Bir FlatMap işlevi, bir öğeyi özel koda (geliştirici tarafından belirtilir) göre girdi işlemi olarak alır ve bir seferde 0 veya daha fazla öğe döndürür. flatMap
() N uzunluğunda bir RDD'yi M uzunluğunda başka bir RDD'ye dönüştürür.
flatMap
Scala kullanımına örnek :
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)
Fark aşağıdaki örnek pyspark kodundan görülebilir:
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 ve Map, koleksiyonu dönüştürür.
Fark:
map (fonk)
Kaynağın her elemanını bir fonksiyon fonkusundan geçirerek oluşturulan yeni dağıtılmış veri kümesini döndürür.
flatMap (fonk)
Haritaya benzer, ancak her girdi öğesi 0 veya daha fazla çıktı öğesine eşlenebilir (bu nedenle işlev, tek bir öğe yerine Seq döndürmelidir).
Dönüştürme işlevi:
map : Bir öğe girişi -> bir öğe çıkışı.
flatMap : -> 0 veya daha fazla öğe içeren bir öğe (bir koleksiyon).
RDD.map
tek bir dizideki tüm öğeleri döndürür
RDD.flatMap
Dizi Dizileri'ndeki öğeleri döndürür
metin.txt dosyasında şu şekilde metin bulunduğumuzu varsayalım:
Spark is an expressive framework
This text is to understand map and faltMap functions of Spark RDD
Haritayı kullanma
val text=sc.textFile("text.txt").map(_.split(" ")).collect
çıktı:
text: **Array[Array[String]]** = Array(Array(Spark, is, an, expressive, framework), Array(This, text, is, to, understand, map, and, faltMap, functions, of, Spark, RDD))
FlatMap kullanma
val text=sc.textFile("text.txt").flatMap(_.split(" ")).collect
çıktı:
text: **Array[String]** = Array(Spark, is, an, expressive, framework, This, text, is, to, understand, map, and, faltMap, functions, of, Spark, RDD)
PySpark ile ilgili isteyenler için:
Örnek dönüşüm: flatMap
>>> a="hello what are you doing"
>>> a.split()
['Merhaba ne yapıyorsun']
>>> b=["hello what are you doing","this is rak"]
>>> b.split()
İzleme
>>> rline=sc.parallelize(b)
>>> type(rline)
>>> def fwords(x):
... return x.split()
>>> rword=rline.map(fwords)
>>> rword.collect()
[['merhaba', 'ne', 'vardır', 'siz', 'yapıyor'], ['bu', '', 'rak']]]
>>> rwordflat=rline.flatMap(fwords)
>>> rwordflat.collect()
['merhaba', 'ne', 'vardır', 'siz', 'yapıyor', 'bu', '', 'rak']
Umarım yardımcı olur :)
map
: RDD
Öğesinin her öğesine bir işlev uygulayarak yeni bir değer döndürür RDD
. .Map içindeki işlev yalnızca bir öğe döndürebilir.
flatMap
: Benzer yeni bir döner, haritaya RDD
göre RDD her öğesi için bir işlev uygulayarak, ancak çıkış düzleşir.
Ayrıca, flatMap
bir öğe listesi döndürebilir (0 veya daha fazla)
Örneğin:
sc.parallelize([3,4,5]).map(lambda x: range(1,x)).collect()
Çıktı: [[1, 2], [1, 2, 3], [1, 2, 3, 4]]
sc.parallelize([3,4,5]).flatMap(lambda x: range(1,x)).collect()
Çıktı: o / p bildirimi tek bir listede düzleştirilir [1, 2, 1, 2, 3, 1, 2, 3, 4]
Kaynak: https://www.linkedin.com/pulse/difference-between-map-flatmap-transformations-spark-pyspark-pandey/
harita:
işlevi bir işlevi girdi olarak alan ve kaynak RDD'deki her öğeye uygulayan daha üst düzey bir yöntemdir.
düz harita:
giriş işlevini alan daha yüksek bir yöntem ve dönüştürme işlemi.
Harita ve flatMap çıktılarındaki fark:
1.flatMap
val a = sc.parallelize(1 to 10, 5)
a.flatMap(1 to _).collect()
Çıktı:
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()
Çıktı:
3 6 6 3 8
whiles
RDD.map
veRDD.flatMap
içinde istediğinizi varsayalım . Genel olarak, Spark'ın RDD operasyonları karşılık gelen Scala toplama operasyonlarından sonra modellenir. Scala arasındaki ve Scala arasındaki farkı tartışan stackoverflow.com/q/1059776/590203 adresindeki yanıtlar size yardımcı olabilir.map
flatMap