zoukankan      html  css  js  c++  java
  • ValueError: Some of types cannot be determined by the first 100 rows, please try again with sampling

    ValueError: Some of types cannot be determined by the first 100 rows, please try again with sampling

    在spark中试图将RDD转换成DataFrame时,有时会提示ValueError: Some of types cannot be determined by the first 100 rows, please try again with sampling,此时有2种解决方案:一是提高数据采样率(sampling ratio),二是显式声明要创建的DataFrame的数据结构,即schema。

    第一种方案具体做法如下:

    sqlContext.createDataFrame(rdd, samplingRatio=0.2)

    其中的samplingRatio参数就是数据采样率,可以先设置为0.2试试,如果不行,可以继续增加。

    其原理在于,RDD中元素的内部结构是未知的、不明确的,也就是说每个元素里面有哪些字段,每个字段是什么类型,这些都是不知道的,而DataFrame则要求对元素的内部结构有完全的知情权。

    比如有一个RDD,其中的元素是dict类型,在使用sqlContext.createDataFrame()方法将该RDD转换成DataFrame的时候,如果括号中没有传入schema参数,那么spark会根据RDD中的前N个元素去猜测元素的内部结构,猜出里面都有哪些字段,每个字段是什么数据类型的。至于N是多少,取决于samplingRatio参数的值,如果不设该参数,则默认取前100个元素。上面代码中设置的samplingRatio是0.2,意味着spark将会取RDD中前20%的元素作为样本去推断元素中各个字段的数据类型。假如运气好,这20%的元素中各个字段都是齐备的,并且能根据字段值判断出该字段的类型,像下图这样:

    ['name':'Tom', 'age':23, 'gender':'M', 'is_married':False]
    ['name':'Jerry', 'age':31, 'gender':'F', 'is_married':True]
    ['name':'John', 'age':27, 'gender':'M', 'is_married':False]

    那么spark就能根据上图中的这么多样本元素推断出元素内部有name、age、gender、is_married这几个字段,且字段类型分别是String,Int,String,Boolean,那就不会报任何错误。

    但是,如果这20%的元素都缺失了某个字段,像下图这样:

    ['name':'Tom', 'age':23, 'gender':'M']
    ['name':'Jerry', 'age':31, 'gender':'F']
    ['name':'John', 'age':27, 'gender':'M']

    本来元素中其实有4个字段的,但是抽样的20%数据里面都缺失了is_married字段,这样就会导致spark误以为元素中只有3个字段,然而当真的按照3个字段来处理时,却又发现后面有其他元素不止这3个字段,这就尴尬了,然后spark觉得自己被耍了,就罢工了。

    还有一种情况也会导致spark报错,像下图这样:

    ['name':'Tom', 'age':23, 'gender':'M', 'is_married':None]
    ['name':'Jerry', 'age':31, 'gender':'F', 'is_married':None]
    ['name':'John', 'age':27, 'gender':'M', 'is_married':None]

    这种情况下,由于抽样的20%的元素中is_married字段值全都是None,导致spark误以为该字段就是None类型的,当按照None处理时,如果发现后面有元素的is_married字段的值是True或者False,然后spark就崩溃了,不是说好了是None类型拉钩上吊一百年不许变吗?你给我来个True和False是个什么意思?

    看到这里,智商超群的你可能已经想到,我主动告诉spark每个RDD元素内部结构是什么样的不就行了吗?没错,这就是我说的第二种方案,显式声明schema。在sqlContext.createDataFrame()方法中,有个参数叫schema,这个参数就是用来告诉spark每个RDD元素的结构的。具体做法是这样的:

    from pyspark.sql.types import *
    schema = StructType([
        StructField("column_1", StringType(), True),
        StructField("column_2", IntegerType(), True)
        .
        .
        .
    ])
    df = sqlContext.createDataFrame(rdd, schema=schema)

    当你显式声明schema并应用到createDataFrame方法中后,就不再需要samplingRatio参数了。实际开发工程中建议使用显式声明schema的方案,这样可以避免出现因奇葩数据导致的错误。

  • 相关阅读:
    SAP 移动类型 整理
    VB6及VS2005 相关的 树TREE控件,网格控件、电子表格控件、网络图及甘持图控件(项目进度)
    金蝶 PK 用友,第三方评论与自我评价(1)
    谁在开发“工作流”WORKFLOW 产品?
    协同及ERP开发平台,我们如何选择?
    关注“北京广联达软件公司”的项目成本管理系统 !
    一个免费提供的开发平台___"KCOM 商业工程"
    企业 ISO“质量、安全和环境” 三大体系认证的管理系统的开发者 !
    MAXWELL 万胜系统软件公司——为工程建设承包商提供优秀的软件套件!
    Contractor Anywhere (任何地方的承包商)也被 SAGE “赛捷”公司收购 !
  • 原文地址:https://www.cnblogs.com/xzjf/p/9296278.html
Copyright © 2011-2022 走看看