代码之家  ›  专栏  ›  技术社区  ›  M Hossain

在pyspark中指定对不同数据类型的多列数据类型更改

  •  0
  • M Hossain  · 技术社区  · 7 年前

    我有一个数据框架( df )它由50多列和不同类型的数据类型组成,例如

    df3.printSchema()
    
    
         CtpJobId: string (nullable = true)
     |-- TransformJobStateId: string (nullable = true)
     |-- LastError: string (nullable = true)
     |-- PriorityDate: string (nullable = true)
     |-- QueuedTime: string (nullable = true)
     |-- AccurateAsOf: string (nullable = true)
     |-- SentToDevice: string (nullable = true)
     |-- StartedAtDevice: string (nullable = true)
     |-- ProcessStart: string (nullable = true)
     |-- LastProgressAt: string (nullable = true)
     |-- ProcessEnd: string (nullable = true)
     |-- ClipFirstFrameNumber: string (nullable = true)
     |-- ClipLastFrameNumber: double (nullable = true)
     |-- SourceNamedLocation: string (nullable = true)
     |-- TargetId: string (nullable = true)
     |-- TargetNamedLocation: string (nullable = true)
     |-- TargetDirectory: string (nullable = true)
     |-- TargetFilename: string (nullable = true)
     |-- Description: string (nullable = true)
     |-- AssignedDeviceId: string (nullable = true)
     |-- DeviceResourceId: string (nullable = true)
     |-- DeviceName: string (nullable = true)
     |-- srcDropFrame: string (nullable = true)
     |-- srcDuration: double (nullable = true)
     |-- srcFrameRate: double (nullable = true)
     |-- srcHeight: double (nullable = true)
     |-- srcMediaFormat: string (nullable = true)
     |-- srcWidth: double (nullable = true)
    

    现在,我希望所有一种类型的列都可以一次性更改,例如

    timestamp_type = [
        'PriorityDate', 'QueuedTime', 'AccurateAsOf', 'SentToDevice', 
        'StartedAtDevice', 'ProcessStart', 'LastProgressAt', 'ProcessEnd'
    ]
    
    
    integer_type = [
        'ClipFirstFrameNumber', 'ClipLastFrameNumber', 'TargetId', 'srcHeight',
        'srcMediaFormat', 'srcWidth'
    ]
    

    我知道如何一个接一个地做,就像我现在做的一样。

    df3 = df3.withColumn("PriorityDate", df3["PriorityDate"].cast(TimestampType()))
    df3 = df3.withColumn("QueuedTime", df3["QueuedTime"].cast(TimestampType()))
    df3 = df3.withColumn("AccurateAsOf", df3["AccurateAsOf"].cast(TimestampType())
    
    df3= df3.withColumn("srcMediaFormat", df3["srcMediaFormat"].cast(IntegerType()))
    df3= df3.withColumn("DeviceResourceId", df3["DeviceResourceId"].cast(IntegerType()))
    df3= df3.withColumn("AssignedDeviceId", df3["AssignedDeviceId"].cast(IntegerType()))
    

    但这看起来很难看,很容易我错过了任何我想改变的专栏。是否有任何方法可以编写任何函数来处理相同类型的要更改的列列表,这样我就可以轻松地实现转换数据类型并传递这些列的名称。 提前谢谢

    1 回复  |  直到 7 年前
        1
  •  2
  •   pault Tanjin    7 年前

    不要枚举所有值,应该使用循环:

    for c in timestamp_type:
        df3 = df3.withColumn(c, df[c].cast(TimestampType()))
    
    for c in integer_type:
        df3 = df3.withColumn(c, df[c].cast(IntegerType()))
    

    或者同等的,你可以使用 functools.reduce :

    from functools import reduce   # not needed in python 2
    df3 = reduce(
        lambda df, c: df.withColumn(c, df[c].cast(TimestampType())), 
        timestamp_type,
        df3
    )
    
    df3 = reduce(
        lambda df, c: df.withColumn(c, df[c].cast(IntegerType())),
        integer_type,
        df3
    )
    
    推荐文章