Spark DataFrame'e (PySpark kullanarak) nasıl yeni bir sütun eklerim?


129

Bir Spark DataFrame'im var (PySpark 1.5.1 kullanarak) ve yeni bir sütun eklemek istiyorum.

Aşağıdakileri herhangi bir başarı olmadan denedim:

type(randomed_hours) # => list

# Create in Python and transform to RDD

new_col = pd.DataFrame(randomed_hours, columns=['new_col'])

spark_new_col = sqlContext.createDataFrame(new_col)

my_df_spark.withColumn("hours", spark_new_col["new_col"])

Ayrıca bunu kullanırken bir hata var:

my_df_spark.withColumn("hours",  sc.parallelize(randomed_hours))

Peki PySpark ile mevcut bir DataFrame'e (Python vektörüne dayalı olarak) yeni bir sütun nasıl ekleyebilirim?

Yanıtlar:


208

Spark'ta rastgele bir sütun ekleyemezsiniz DataFrame. Yeni sütunlar yalnızca değişmez değerler kullanılarak oluşturulabilir (diğer değişmez türler Spark DataFrame'e sabit sütun nasıl eklenir? Bölümünde açıklanmıştır. )

from pyspark.sql.functions import lit

df = sqlContext.createDataFrame(
    [(1, "a", 23.0), (3, "B", -23.0)], ("x1", "x2", "x3"))

df_with_x4 = df.withColumn("x4", lit(0))
df_with_x4.show()

## +---+---+-----+---+
## | x1| x2|   x3| x4|
## +---+---+-----+---+
## |  1|  a| 23.0|  0|
## |  3|  B|-23.0|  0|
## +---+---+-----+---+

mevcut bir sütunu dönüştürmek:

from pyspark.sql.functions import exp

df_with_x5 = df_with_x4.withColumn("x5", exp("x3"))
df_with_x5.show()

## +---+---+-----+---+--------------------+
## | x1| x2|   x3| x4|                  x5|
## +---+---+-----+---+--------------------+
## |  1|  a| 23.0|  0| 9.744803446248903E9|
## |  3|  B|-23.0|  0|1.026187963170189...|
## +---+---+-----+---+--------------------+

dahil join:

from pyspark.sql.functions import exp

lookup = sqlContext.createDataFrame([(1, "foo"), (2, "bar")], ("k", "v"))
df_with_x6 = (df_with_x5
    .join(lookup, col("x1") == col("k"), "leftouter")
    .drop("k")
    .withColumnRenamed("v", "x6"))

## +---+---+-----+---+--------------------+----+
## | x1| x2|   x3| x4|                  x5|  x6|
## +---+---+-----+---+--------------------+----+
## |  1|  a| 23.0|  0| 9.744803446248903E9| foo|
## |  3|  B|-23.0|  0|1.026187963170189...|null|
## +---+---+-----+---+--------------------+----+

veya function / udf ile oluşturulmuş:

from pyspark.sql.functions import rand

df_with_x7 = df_with_x6.withColumn("x7", rand())
df_with_x7.show()

## +---+---+-----+---+--------------------+----+-------------------+
## | x1| x2|   x3| x4|                  x5|  x6|                 x7|
## +---+---+-----+---+--------------------+----+-------------------+
## |  1|  a| 23.0|  0| 9.744803446248903E9| foo|0.41930610446846617|
## |  3|  B|-23.0|  0|1.026187963170189...|null|0.37801881545497873|
## +---+---+-----+---+--------------------+----+-------------------+

pyspark.sql.functionsCatalyst ifadesiyle eşleşen performans açısından yerleşik işlevler ( ) genellikle Python kullanıcı tanımlı işlevlere tercih edilir.

Bir sütun olarak rastgele bir RDD içeriği eklemek isterseniz, şunları yapabilirsiniz:


1
"Yeni sütunlar yalnızca değişmez değerler kullanılarak oluşturulabilir" Bu bağlamda değişmez değerler tam olarak ne anlama geliyor?
timbram

Spark'ın Dokümantasyonu harika, bkz. Df.withColumn spark.apache.org/docs/2.1.0/api/python/…
Steven Black

10
Kıvılcım dokümantasyonu, sadece zeki okuyucu için bir alıştırmaya kadar büyük kullanım alanları bıraktığı için "harika". Spark (ve Pyspark), aralarında nasıl dönüştürüleceğine dair çok az talimatla veya hiç talimat olmadan gerçek bir veri yapıları hayvanat bahçesini kapsar. Örnek olay: Tıpkı bunun gibi soruların çoğalması.
shadowtalker

62

Bir UDF kullanarak bir sütun eklemek için:

df = sqlContext.createDataFrame(
    [(1, "a", 23.0), (3, "B", -23.0)], ("x1", "x2", "x3"))

from pyspark.sql.functions import udf
from pyspark.sql.types import *

def valueToCategory(value):
   if   value == 1: return 'cat1'
   elif value == 2: return 'cat2'
   ...
   else: return 'n/a'

# NOTE: it seems that calls to udf() must be after SparkContext() is called
udfValueToCategory = udf(valueToCategory, StringType())
df_with_cat = df.withColumn("category", udfValueToCategory("x1"))
df_with_cat.show()

## +---+---+-----+---------+
## | x1| x2|   x3| category|
## +---+---+-----+---------+
## |  1|  a| 23.0|     cat1|
## |  3|  B|-23.0|      n/a|
## +---+---+-----+---------+

30

İçin Spark 2.0

# assumes schema has 'age' column 
df.select('*', (df.age + 10).alias('agePlusTen'))

1
İhtiyaç df.select olmak ( '*', (df.age + 10) .alias ( 'agePlusTen'))
Frank B.

1
Teşekkürler ve df = df.select('*', (df.age + 10).alias('agePlusTen'))girerseniz, @ zero323'ün yukarıda bizi uyardığı gibi etkin bir şekilde rastgele bir sütun ekliyorsunuz, Spark'ta bunu yapmakta bir sorun yoksa, Pandas'ta bu standart bir yoldur ..
kakule

Bunun pySpark için bir versiyonu var mı?
Tagar

@Tagar Snippet'in yukarısı python.
Luke W

1
@GeoffreyAnderson,df.select('*', df.age + 10, df.age + 20)
Mark Rajcok

2

PySpark'a yeni bir sütun eklemenin birden fazla yolu vardır.

Önce basit bir DataFrame oluşturalım.

date = [27, 28, 29, None, 30, 31]
df = spark.createDataFrame(date, IntegerType())

Şimdi sütun değerini ikiye katlamayı ve yeni bir sütunda saklamayı deneyelim. PFB aynı şeyi başarmak için birkaç farklı yaklaşım.

# Approach - 1 : using withColumn function
df.withColumn("double", df.value * 2).show()

# Approach - 2 : using select with alias function.
df.select("*", (df.value * 2).alias("double")).show()

# Approach - 3 : using selectExpr function with as clause.
df.selectExpr("*", "value * 2 as double").show()

# Approach - 4 : Using as clause in SQL statement.
df.createTempView("temp")
spark.sql("select *, value * 2 as double from temp").show()

Daha fazla örnek ve kıvılcım DataFrame fonksiyonları üzerine açıklama için, sen benim gidebilir blog .

Umarım bu yardımcı olur.


0

Bir udfeklerken yeni bir tanımlayabilirsiniz column_name:

u_f = F.udf(lambda :yourstring,StringType())
a.select(u_f().alias('column_name')

0
from pyspark.sql.functions import udf
from pyspark.sql.types import *
func_name = udf(
    lambda val: val, # do sth to val
    StringType()
)
df.withColumn('new_col', func_name(df.old_col))

Aramalısın StringType().
gberger

0

Çok benzer bir kullanım durumu için genelleştirilmiş bir örnek sunmak istiyorum:

Kullanım Örneği: Şunlardan oluşan bir csv'ye sahibim:

First|Third|Fifth
data|data|data
data|data|data
...billion more lines

Bazı dönüşümler yapmam gerekiyor ve son csv'nin şöyle görünmesi gerekiyor

First|Second|Third|Fourth|Fifth
data|null|data|null|data
data|null|data|null|data
...billion more lines

Bunu yapmam gerekiyor çünkü bu bir model tarafından tanımlanan şema ve son verilerimin SQL Toplu Eklemeler ve benzeri şeyler ile birlikte çalışabilir olması gerekiyor.

yani:

1) Orijinal csv'yi spark.read kullanarak okudum ve ona "df" diyorum.

2) Verilere bir şeyler yapıyorum.

3) Bu komut dosyasını kullanarak boş sütunları ekliyorum:

outcols = []
for column in MY_COLUMN_LIST:
    if column in df.columns:
        outcols.append(column)
    else:
        outcols.append(lit(None).cast(StringType()).alias('{0}'.format(column)))

df = df.select(outcols)

Bu şekilde, bir csv yükledikten sonra şemanızı yapılandırabilirsiniz (bunu birçok tablo için yapmanız gerekiyorsa sütunları yeniden düzenlemek için de işe yarar).


0

Bir sütun eklemenin en basit yolu "withColumn" kullanmaktır. Veri çerçevesi sqlContext kullanılarak oluşturulduğundan, şemayı belirtmeniz gerekir veya varsayılan olarak veri kümesinde kullanılabilir. Şema belirtilirse, her seferinde değiştirildiğinde iş yükü sıkıcı hale gelir.

Aşağıda dikkate alabileceğiniz bir örnek verilmiştir:

from pyspark.sql import SQLContext
from pyspark.sql.types import *
sqlContext = SQLContext(sc) # SparkContext will be sc by default 

# Read the dataset of your choice (Already loaded with schema)
Data = sqlContext.read.csv("/path", header = True/False, schema = "infer", sep = "delimiter")

# For instance the data has 30 columns from col1, col2, ... col30. If you want to add a 31st column, you can do so by the following:
Data = Data.withColumn("col31", "Code goes here")

# Check the change 
Data.printSchema()

0

DataFrame'e doğrudan aşağıdaki adımlarla ek sütunlar ekleyebiliriz:

from pyspark.sql.functions import when
df = spark.createDataFrame([["amit", 30], ["rohit", 45], ["sameer", 50]], ["name", "age"])
df = df.withColumn("profile", when(df.age >= 40, "Senior").otherwise("Executive"))
df.show()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.