Pyspark में डेटाफ्रेम कॉलम नाम कैसे बदलें?


201

मैं पांडा बैकग्राउंड से आता हूं और सीएसवी फाइलों के डेटा को डेटाफ्रेम में पढ़ने के लिए इस्तेमाल किया जाता है और फिर कॉलम के नाम को साधारण कमांड का उपयोग करके कुछ उपयोगी में बदल दिया जाता है:

df.columns = new_column_name_list

हालांकि, वही sqlContext का उपयोग करके बनाए गए pyspark डेटाफ़्रेम में काम नहीं करता है। एकमात्र उपाय जिसे मैं आसानी से करने के लिए समझ सकता हूं वह निम्नलिखित है:

df = sqlContext.read.format("com.databricks.spark.csv").options(header='false', inferschema='true', delimiter='\t').load("data.txt")
oldSchema = df.schema
for i,k in enumerate(oldSchema.fields):
  k.name = new_column_name_list[i]
df = sqlContext.read.format("com.databricks.spark.csv").options(header='false', delimiter='\t').load("data.txt", schema=oldSchema)

यह मूल रूप से चर को दो बार परिभाषित कर रहा है और पहले स्कीमा का संदर्भ दे रहा है फिर कॉलम नामों का नाम बदल रहा है और फिर अद्यतन स्कीमा के साथ फिर से डेटाफ्रेम लोड कर रहा है।

क्या ऐसा करने का एक बेहतर और कारगर तरीका है जैसे हम पांडा में करते हैं?

मेरा स्पार्क संस्करण 1.5.0 है

जवाबों:


334

ऐसा करने के कई तरीके हैं:

  • विकल्प 1. selectExpr का उपयोग करना ।

    data = sqlContext.createDataFrame([("Alberto", 2), ("Dakota", 2)], 
                                      ["Name", "askdaosdka"])
    data.show()
    data.printSchema()
    
    # Output
    #+-------+----------+
    #|   Name|askdaosdka|
    #+-------+----------+
    #|Alberto|         2|
    #| Dakota|         2|
    #+-------+----------+
    
    #root
    # |-- Name: string (nullable = true)
    # |-- askdaosdka: long (nullable = true)
    
    df = data.selectExpr("Name as name", "askdaosdka as age")
    df.show()
    df.printSchema()
    
    # Output
    #+-------+---+
    #|   name|age|
    #+-------+---+
    #|Alberto|  2|
    #| Dakota|  2|
    #+-------+---+
    
    #root
    # |-- name: string (nullable = true)
    # |-- age: long (nullable = true)
  • विकल्प 2। का उपयोग कर ColumnRenamed , ध्यान दें कि यह विधि आपको एक ही कॉलम को "अधिलेखित" करने की अनुमति देती है। पायथन 3 के लिए, के xrangeसाथ बदलें range

    from functools import reduce
    
    oldColumns = data.schema.names
    newColumns = ["name", "age"]
    
    df = reduce(lambda data, idx: data.withColumnRenamed(oldColumns[idx], newColumns[idx]), xrange(len(oldColumns)), data)
    df.printSchema()
    df.show()
  • विकल्प 3. का उपयोग कर उर्फ , स्काला में आप भी उपयोग कर सकते हैं के रूप में

    from pyspark.sql.functions import col
    
    data = data.select(col("Name").alias("name"), col("askdaosdka").alias("age"))
    data.show()
    
    # Output
    #+-------+---+
    #|   name|age|
    #+-------+---+
    #|Alberto|  2|
    #| Dakota|  2|
    #+-------+---+
  • विकल्प 4. sqlContext.sql का उपयोग करना , जो आपको DataFramesतालिकाओं के रूप में पंजीकृत एसक्यूएल प्रश्नों का उपयोग करने देता है ।

    sqlContext.registerDataFrameAsTable(data, "myTable")
    df2 = sqlContext.sql("SELECT Name AS name, askdaosdka as age from myTable")
    
    df2.show()
    
    # Output
    #+-------+---+
    #|   name|age|
    #+-------+---+
    #|Alberto|  2|
    #| Dakota|  2|
    #+-------+---+

1
मैंने इसे forलूप + के साथ किया withColumnRenamed, लेकिन आपका reduceविकल्प बहुत अच्छा है :)
फेलिप जेरार्ड

1
खैर चूंकि स्पार्क में कुछ भी नहीं किया जाता है जब तक कि डीएफ पर कार्रवाई नहीं की जाती है, यह सिर्फ कम सुरुचिपूर्ण कोड है ... अंत में परिणामस्वरूप डीएफ बिल्कुल समान है!
फेलिप जेरार्ड

2
@FelipeGerard कृपया इस पोस्ट को देखें , यदि आपके पास कई कॉलम हैं तो खराब चीजें हो सकती हैं।
अल्बर्टो बोन्सेंटो

1
@AlbertoBonsanto यदि 100 से अधिक कॉलम हैं, तो उपनाम का चयन कैसे करें जो सबसे अच्छा विकल्प है

3
@NuValue, आपको पहले चलना चाहिएfrom functools import reduce
joaofbsm

169
df = df.withColumnRenamed("colName", "newColName")
       .withColumnRenamed("colName2", "newColName2")

इस तरह से उपयोग करने का लाभ: स्तंभों की लंबी सूची के साथ आप केवल कुछ स्तंभ नामों को बदलना चाहेंगे। इन परिदृश्यों में यह बहुत सुविधाजनक हो सकता है। डुप्लिकेट कॉलम नामों के साथ तालिकाओं में शामिल होने पर बहुत उपयोगी है।


क्या इस समाधान का एक प्रकार है जो अन्य सभी स्तंभों को अपरिवर्तित छोड़ देता है? इस पद्धति के साथ, और अन्य, केवल स्पष्ट रूप से नामित कॉलम बने रहे (सभी अन्य हटा दिए गए)
Quetzalcoatl

1
+1 ने मेरे लिए ठीक काम किया, बस निर्दिष्ट कॉलम को दूसरों को अपरिवर्तित संपादित किया और कोई कॉलम हटाया नहीं गया।
mnis.p

2
@Quetzalcoatl यह आदेश अन्य सभी स्तंभों को बनाए रखते हुए केवल निर्दिष्ट कॉलम को बदलने के लिए प्रकट होता है। इसलिए, संभावित रूप से कई स्तंभ नामों में से एक का नाम बदलने के लिए एक महान आदेश
user989762

@ user989762: सहमत; मेरी शुरुआती समझ इस पर गलत थी ...!
क्वेटज़लकोटल

62

यदि आप सभी कॉलम नामों को बदलना चाहते हैं, तो प्रयास करें df.toDF(*cols)


5
यह समाधान ओपी के अनुसार df.columns = new_column_name_list के सबसे करीब है, यह कितना संक्षिप्त है और इसका निष्पादन दोनों है।
Quetzalcoatl

मुझे लगता है कि इसे सर्वश्रेष्ठ उत्तर के रूप में चुना जाना चाहिए
हानाकेज

मेरे लिए मुझे पंडों के df = df.toDF(*my_pandas_df.columns)
डेटाफ्रेम

यह उत्तर मुझे भ्रमित करता है। क्या पुराने कॉलम नामों से लेकर नए नामों तक की मैपिंग नहीं होनी चाहिए? क्या यह colsनया स्तंभ नाम होने से काम करता है , और colsडेटाफ़्रेम के स्तंभ क्रम के अनुरूप नामों के क्रम को मान रहा है ?
rbatt

47

यदि आप सभी कॉलम नामों पर एक साधारण परिवर्तन लागू करना चाहते हैं, तो यह कोड ट्रिक करता है: (मैं सभी स्पेस को अंडरसर्स के साथ बदल रहा हूं)

new_column_name_list= list(map(lambda x: x.replace(" ", "_"), df.columns))

df = df.toDF(*new_column_name_list)

toDfट्रिक के लिए @ user8117731 को धन्यवाद ।


14

यदि आप किसी एकल स्तंभ का नाम बदलना चाहते हैं और शेष को यथावत रखें:

from pyspark.sql.functions import col
new_df = old_df.select(*[col(s).alias(new_name) if s == column_to_change else s for s in old_df.columns])

14

df.withColumnRenamed('age', 'age2')


1
पंकज कुमार का जवाब और अल्बर्टो बोनसेंटो का जवाब (जो क्रमशः 2016 और 2015 से हैं) पहले से ही उपयोग करने का सुझाव देते हैं withColumnRenamed
एंड्रयू मायर्स

धन्यवाद, हाँ, लेकिन कुछ अलग वाक्यविन्यास हैं, शायद हमें उन्हें और अधिक औपचारिक उत्तर में इकट्ठा करना चाहिए? data.withColumnRenamed (oldColumns [idx], newColumns [idx]) बनाम data.withColumnRenamed (कॉलमनाम, नया कॉलमनाम) मुझे लगता है कि यह आपके उपयोग के pyspark के किस संस्करण पर निर्भर करता है
Sahan Jayasumana

1
यह एक अलग वाक्यविन्यास नहीं है। एकमात्र अंतर यह है कि आपने अपने कॉलम नामों को किसी सरणी में संग्रहीत नहीं किया है।
एड बोर्डिन

13

यह वह तरीका है जो मैंने इस्तेमाल किया है:

pyspark सत्र बनाएँ:

import pyspark
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('changeColNames').getOrCreate()

डेटाफ़्रेम बनाएँ:

df = spark.createDataFrame(data = [('Bob', 5.62,'juice'),  ('Sue',0.85,'milk')], schema = ["Name", "Amount","Item"])

स्तंभ नामों के साथ df देखें:

df.show()
+----+------+-----+
|Name|Amount| Item|
+----+------+-----+
| Bob|  5.62|juice|
| Sue|  0.85| milk|
+----+------+-----+

नए कॉलम नामों के साथ एक सूची बनाएं:

newcolnames = ['NameNew','AmountNew','ItemNew']

df के कॉलम नाम बदलें:

for c,n in zip(df.columns,newcolnames):
    df=df.withColumnRenamed(c,n)

नए कॉलम नामों के साथ df देखें:

df.show()
+-------+---------+-------+
|NameNew|AmountNew|ItemNew|
+-------+---------+-------+
|    Bob|     5.62|  juice|
|    Sue|     0.85|   milk|
+-------+---------+-------+

9

यदि कोई इसका उपयोग करना चाहता है, तो मैंने एक pyspark डेटाफ़्रेम के लिए कई स्तंभों का नाम बदलने के लिए फ़ंक्शन का उपयोग करना आसान बना दिया है:

def renameCols(df, old_columns, new_columns):
    for old_col,new_col in zip(old_columns,new_columns):
        df = df.withColumnRenamed(old_col,new_col)
    return df

old_columns = ['old_name1','old_name2']
new_columns = ['new_name1', 'new_name2']
df_renamed = renameCols(df, old_columns, new_columns)

सावधान रहें, दोनों सूचियों की लंबाई समान होनी चाहिए।


1
इस पर अच्छा काम किया। हालांकि मैं क्या जरूरत के लिए overkill का एक सा। और आप सिर्फ df पास कर सकते हैं क्योंकि old_columnsजैसा होगा वैसा ही होगा df.columns
डार्थ एलीगस

7

सिर्फ एक कॉलम (उपयोग करके import pyspark.sql.functions as F) का नाम बदलने का दूसरा तरीका :

df = df.select( '*', F.col('count').alias('new_count') ).drop('count')

3

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

from pyspark.sql.functions import col
df.select(['vin',col('timeStamp').alias('Date')]).show()

2
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
इस्मा

1

आप अपने डेटाफ़्रेम के सभी स्तंभों का नाम बदलने के लिए निम्न फ़ंक्शन का उपयोग कर सकते हैं।

def df_col_rename(X, to_rename, replace_with):
    """
    :param X: spark dataframe
    :param to_rename: list of original names
    :param replace_with: list of new names
    :return: dataframe with updated names
    """
    import pyspark.sql.functions as F
    mapping = dict(zip(to_rename, replace_with))
    X = X.select([F.col(c).alias(mapping.get(c, c)) for c in to_rename])
    return X

यदि आपको केवल कुछ कॉलम के नामों को अपडेट करने की आवश्यकता है, तो आप उसी कॉलम के नाम को प्रतिस्थापन_ सूची में उपयोग कर सकते हैं

सभी स्तंभों का नाम बदलने के लिए

df_col_rename(X,['a', 'b', 'c'], ['x', 'y', 'z'])

कुछ स्तंभों का नाम बदलने के लिए

df_col_rename(X,['a', 'b', 'c'], ['a', 'y', 'z'])

0

एकल स्तंभ नाम बदलने के लिए, आप अभी भी toDF () का उपयोग कर सकते हैं। उदाहरण के लिए,

df1.selectExpr("SALARY*2").toDF("REVISED_SALARY").show()

0

हम कॉलम नाम का नाम बदलने के लिए विभिन्न तरीकों का उपयोग कर सकते हैं।

सबसे पहले, एक सरल DataFrame बनाएँ।

df = spark.createDataFrame([("x", 1), ("y", 2)], 
                                  ["col_1", "col_2"])

अब चलिए col_1 को col_3 का नाम बदलने का प्रयास करते हैं। PFB कुछ ही करने के लिए दृष्टिकोण।

# Approach - 1 : using withColumnRenamed function.
df.withColumnRenamed("col_1", "col_3").show()

# Approach - 2 : using alias function.
df.select(df["col_1"].alias("col3"), "col_2").show()

# Approach - 3 : using selectExpr function.
df.selectExpr("col_1 as col_3", "col_2").show()

# Rename all columns
# Approach - 4 : using toDF function. Here you need to pass the list of all columns present in DataFrame.
df.toDF("col_3", "col_2").show()

यहाँ आउटपुट है।

+-----+-----+
|col_3|col_2|
+-----+-----+
|    x|    1|
|    y|    2|
+-----+-----+

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

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