簡體   English   中英

比較兩個數據框pyspark中的列名

[英]Compare column names in two data frames pyspark

我在pyspark dfdata有兩個數據幀。 架構如下

>>> df.printSchema()
root
 |-- id: integer (nullable = false)
 |-- name: string (nullable = true)
 |-- address: string (nullable = true)
 |-- nation: string (nullable = true)
 |-- Date: timestamp (nullable = false)
 |-- ZipCode: integer (nullable = true)
 |-- car: string (nullable = true)
 |-- van: string (nullable = true)

>>> data.printSchema()
root 
 |-- id: integer (nullable = true)
 |-- name: string (nullable = true)
 |-- address: string (nullable = true)
 |-- nation: string (nullable = true)
 |-- date: string (nullable = true)
 |-- zipcode: integer (nullable = true)

現在,我想通過比較兩個架構將car和van列添加到我的data數據框中。

如果列相同,我也想比較兩個數據幀,但是如果列不同,則將列添加到沒有列的數據幀中。

我們如何在pyspark中實現這一目標。

僅供參考,我正在使用spark 1.6

一旦將列添加到數據框中。 新添加的數據框中這些列的值應為null。

例如,在這里我們向data數據幀添加列,因此data數據幀中的car和van列應包含空值,但df數據幀中的相同列應具有其原始值

如果要添加兩個以上的新列會發生什么

由於架構不是StructType,而是由StructFields列表組成的,因此我們可以檢索字段列表,以比較並查找缺少的列,

df_schema = df.schema.fields
data_schema = data.schema.fields
df_names = [x.name.lower() for x in df_scehma]
data_names = [x.name.lower() for x in data_schema]
if df_schema <> data_schema:
    col_diff = set(df_names) ^ set(data_names)      
    col_list = [(x[0].name,x[0].dataType) for x in map(None,df_schema,data_schema) if ((x[0] is not None and x[0].name.lower() in col_diff) or x[1].name.lower() in col_diff)]
     for i in col_list:
        if i[0] in df_names:
            data = data.withColumn("%s"%i[0],lit(None).cast(i[1]))
        else:
            df = df.withColumn("%s"%i[0],lit(None).cast(i[1]))
else:
    print "Nothing to do"

您已經提到如果沒有空值則添加該列,但是您的架構差異是可空列,因此沒有使用該檢查。 如果需要,請按如下所示添加可空值檢查,

col_list = [(x[0].name,x[0].dataType) for x in map(None,df_schema,data_schema) if (x[0].name.lower() in col_diff or x[1].name.lower() in col_diff) and not x.nullable]

請查看文檔以獲取有關StructType和StructFields的更多信息, https: //spark.apache.org/docs/1.6.2/api/python/pyspark.sql.html#pyspark.sql.types.StructType

如果必須對多個表執行此操作,則值得對代碼進行泛化。 此代碼采用非匹配源列中的第一個非空值在目標表中創建新列。

from pyspark.sql.functions import lit, first

def first_non_null(f,t): # find the first non-null value of a column
    return f.select(first(f[t], ignorenulls=True)).first()[0]

def match_type(f1,f2,miss): # add missing column to the target table
    for i in miss:
        try:
            f1 = f1.withColumn(i, lit(first_non_null(f2,i)))
        except:
            pass
        try:
            f2 = f2.withColumn(i, lit(first_non_null(f1,i)))
        except:
            pass
    return f1, f2

def column_sync_up(d1,d2): # test if the matching requirement is met
    missing = list(set(d1.columns) ^ set(d2.columns))
    if len(missing)>0:
        return match_type(d1,d2,missing)
    else:
        print "Columns Match!"

df1, df2 = column_sync_up(df1,df2) # reuse as necessary

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM