स्पार्क डेटाफ़्रेम (PySpark का उपयोग करके) में एक नया कॉलम कैसे जोड़ूँ?


128

मेरे पास स्पार्क डेटाफ़्रेम (PySpark 1.5.1 का उपयोग करके) है और एक नया कॉलम जोड़ना चाहूंगा।

मैंने बिना किसी सफलता के निम्नलिखित कोशिश की है:

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"])

इसके उपयोग से एक त्रुटि मिली:

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

तो मैं PySpark के साथ मौजूदा DataFrame में एक नया कॉलम (Python वेक्टर पर आधारित) कैसे जोड़ूं?

जवाबों:


207

आप DataFrameस्पार्क में एक मनमाना कॉलम नहीं जोड़ सकते । नए कॉलम केवल शाब्दिक का उपयोग करके बनाए जा सकते हैं (अन्य शाब्दिक प्रकारों का वर्णन कैसे किया जाता है एक स्पार्कफ्रेम में निरंतर कॉलम कैसे जोड़ें? )

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|
## +---+---+-----+---+

मौजूदा कॉलम को बदलना:

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...|
## +---+---+-----+---+--------------------+

का उपयोग कर शामिल 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|
## +---+---+-----+---+--------------------+----+

या समारोह के साथ उत्पन्न / udf:

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.functions), जो उत्प्रेरक अभिव्यक्ति के लिए मैप करते हैं, आमतौर पर पायथन उपयोगकर्ता परिभाषित कार्यों पर पसंद किए जाते हैं।

यदि आप एक स्तंभ के रूप में मनमाने ढंग से RDD की सामग्री जोड़ना चाहते हैं


1
"नए कॉलम केवल शाब्दिक का उपयोग करके बनाए जा सकते हैं" वास्तव में इस संदर्भ में शाब्दिक अर्थ क्या है?
टाइमब्रम

स्पार्क का दस्तावेजीकरण बहुत अच्छा है, देखें df.withColumn spark.apache.org/docs/2.1.0/api/python/…
स्टीवन ब्लैक

10
स्पार्क डॉक्यूमेंटेशन केवल "महान" है, जिसमें यह एक्सट्रीम रीडर के लिए एक्सरसाइज करने के लिए बहुत सारे स्वैट्स को छोड़ता है। स्पार्क (और पिसपार्क) डेटा संरचनाओं के एक सत्य चिड़ियाघर को कवर करता है, जिनके बीच कम या कोई निर्देश नहीं है कि उनके बीच कैसे कनवर्ट किया जाए। बिंदु में मामला: सवालों का प्रसार इस तरह से एक ही है।
छायाकार

62

UDF का उपयोग करके एक कॉलम जोड़ने के लिए:

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

के लिए स्पार्क 2.0

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

1
Df.select ('* *', (df.age + 10) .alas ('agePlusTen') की आवश्यकता है
फ्रैंक बी।

1
धन्यवाद, और यदि आप दर्ज df = df.select('*', (df.age + 10).alias('agePlusTen'))करते हैं तो आप प्रभावी रूप से एक मनमाना कॉलम जोड़ रहे हैं जैसे @ zero323 ने हमें ऊपर चेतावनी दी थी, जब तक कि स्पार्क में ऐसा करने में कुछ गड़बड़ नहीं है, पंडों में यह मानक तरीका है ..
इलायची

वहाँ pySpark के लिए इस का एक संस्करण है?
तगर

@ सागर के ऊपर स्निपेट अजगर है।
ल्यूक डब्ल्यू

1
@GeoffreyAnderson,df.select('*', df.age + 10, df.age + 20)
मार्क राजकॉक

2

ऐसे कई तरीके हैं जिनसे हम pySpark में एक नया कॉलम जोड़ सकते हैं।

आइए सबसे पहले एक सरल DataFrame बनाएं।

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

अब कॉलम मूल्य को दोगुना करने और इसे नए कॉलम में संग्रहीत करने का प्रयास करते हैं। PFB कुछ अलग ही दृष्टिकोण को प्राप्त करने के लिए।

# 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()

स्पार्क DataFrame फ़ंक्शन पर अधिक उदाहरण और स्पष्टीकरण के लिए, आप मेरे ब्लॉग पर जा सकते हैं ।

आशा है कि ये आपकी मदद करेगा।


0

udfजब आप कोई नया परिभाषित कर सकते हैं 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))

आपको कॉल करने की आवश्यकता है StringType()
गब्बर

0

मैं एक बहुत ही समान उपयोग के मामले के लिए एक सामान्यीकृत उदाहरण देना चाहता हूं:

केस का उपयोग करें: मेरे पास एक csv है:

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

मुझे कुछ परिवर्तन करने की आवश्यकता है और अंतिम सीएसवी को देखने की जरूरत है

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

मुझे ऐसा करने की आवश्यकता है क्योंकि यह कुछ मॉडल द्वारा परिभाषित स्कीमा है और मुझे अपने अंतिम डेटा के लिए SQL बल्क इंसर्ट और इस तरह की चीजों के साथ अंतर करने योग्य होना चाहिए।

इसलिए:

1) मैंने स्पार्क.डर का उपयोग करके मूल सीएसवी पढ़ा और इसे "डीएफ" कहा।

2) मैं डेटा के लिए कुछ करता हूं।

3) मैं इस स्क्रिप्ट का उपयोग करते हुए अशक्त कॉलम जोड़ता हूं:

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)

इस तरह, आप एक सीएसवी लोड करने के बाद अपने स्कीमा को संरचना कर सकते हैं (यदि आप कई तालिकाओं के लिए ऐसा करना चाहते हैं तो स्तंभों को फिर से व्यवस्थित करने के लिए भी काम करेंगे)।


0

एक कॉलम जोड़ने का सबसे सरल तरीका "विदआउट कॉलम" का उपयोग करना है। चूँकि डेटाफ्रेम sqlContext का उपयोग करके बनाया गया है, इसलिए आपको स्कीमा निर्दिष्ट करना होगा या डिफ़ॉल्ट रूप से डेटासेट में उपलब्ध हो सकता है। यदि स्कीमा निर्दिष्ट है, तो हर बार बदलते समय कार्यभार थकाऊ हो जाता है।

नीचे एक उदाहरण है जिस पर आप विचार कर सकते हैं:

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 में अतिरिक्त कॉलम जोड़ सकते हैं:

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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.