区分类型type与编码chardet.detect(),以及中文字符的编码统一处理原理

**
总结1:只有字符类型即str类型的才有编码,整数及其他没有编码,检测编码会报错
总结2:编码:自动编码规则—根据编译环境自动为字符编码,通常,英文字母或数字会编码成ascii,中文会编码成utf-8;
总结3:解码,对于数字和英文字母解码,decode用ascii和utf8解码均能成功,解码成ascii;对于中文字符的解码,decode只能用utf-8解码,ascii解码会报错,中文字符解码后也为ascii;
总结4:加'u'表示Unicode编码,Unicode编码既包括utf-8,也包括ascii,未加u默认中文编码为'utf-8',加了u之后变成英文编码
总结5:对于中文字符的处理——将字符转换成str,再判断str是否是unicode编码,如果是再将其解码成ascii;
**
**只有字符类型即str类型的才有编码,整数及其他没有编码,检测编码会报错**
stra = "中", 则使用type(stra)的结果是<type 'str'>,表明为ascii类型字符串;
strb = u"中", 则使用type(strb)的结果是<type 'unicode'>,表明为unicode类型字符串。
判断类型用type和判断编码用chardet.detect(a)
In[37]: p=1
In[38]: type(1)
Out[38]: int
In[39]: chardet.detect(p)
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
    exec code_obj in self.user_global_ns, self.user_ns
  File "<ipython-input-39-ca1457f42cf7>", line 1, in <module>
    chardet.detect(p)
  File "/usr/lib/python2.7/dist-packages/chardet/__init__.py", line 24, in detect
    u.feed(aBuf)
  File "/usr/lib/python2.7/dist-packages/chardet/universaldetector.py", line 64, in feed
    aLen = len(aBuf)
TypeError: object of type 'int' has no len()

 #**根据编译环境自动为字符编码,通常,英文或数字会编码成ascii,中文会编码成utf-8**
**数字编码**
 p='1' 
In[41]: chardet.detect(p)
Out[41]: {'confidence': 1.0, 'encoding': 'ascii'}
In[42]: p=u'1'
In[43]: chardet.detect(p)
Out[43]: {'confidence': 1.0, 'encoding': 'ascii'}
**字母编码数字**
In[46]: p1=u'a'
In[47]: chardet.detect(p1)
Out[47]: {'confidence': 1.0, 'encoding': 'ascii'}
In[48]: p1='a'
In[49]: chardet.detect(p1)
Out[49]: {'confidence': 1.0, 'encoding': 'ascii'}
**含有中文字符的编码**
In[50]: p2='a好21'
In[51]: chardet.detect(p2)
Out[51]: {'confidence': 0.505, 'encoding': 'utf-8'}
In[52]: p2=u'a好21'
In[53]: chardet.detect(p2)
Out[53]: {'confidence': 1.0, 'encoding': 'ascii'}
############################
解码:
**数字解码**
decode('utf-8')成ascii;
In[57]: chardet.detect(str1)
Out[57]: {'confidence': 1.0, 'encoding': 'ascii'}
In[58]: str1.decode('utf-8')
Out[58]: u'1'
In[59]: chardet.detect(str1)
Out[59]: {'confidence': 1.0, 'encoding': 'ascii'}
**中文解码**
In[62]: str2='哈哈'
In[63]: chardet.detect(str2)
Out[63]: {'confidence': 0.7525, 'encoding': 'utf-8'}
In[64]: str2.decode('utf-8')
Out[64]: u'\u54c8\u54c8'
In[65]: chardet.detect(str2.decode('utf-8'))
Out[65]: {'confidence': 1.0, 'encoding': 'ascii'}
In[72]: str2.decode('ascii')
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
    exec code_obj in self.user_global_ns, self.user_ns
  File "<ipython-input-72-d98396330a85>", line 1, in <module>
    str2.decode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
中文字符用ascii解码会报错;
**字母解码**
In[66]: str3 = 'num'
In[67]: chardet.detect(str3)
Out[67]: {'confidence': 1.0, 'encoding': 'ascii'}
In[68]: str3.decode('utf-8')
Out[68]: u'num'
In[69]: chardet.detect(str3)
Out[69]: {'confidence': 1.0, 'encoding': 'ascii'}
In[70]: str3.decode('ascii')
Out[70]: u'num'
In[71]: chardet.detect(str3)
Out[71]: {'confidence': 1.0, 'encoding': 'ascii'}
############################

通过spark读取的csv,里面的中文字符用法注意,需要加u实现,形如:if big_hy_name in [u'石油加工、炼焦及核燃料加工业',......],
注意:sqlContext.sql语句中可以直接用where big_hy_name = '石油加工、炼焦及核燃料加工业',不需要加u;

encode()对字符串编码
decode()对字符串解码
**对于一个正常的未加u的字符串,其编码方式是由默认的编码设置决定的;**
小案例:
######################################
**情况1 —— python中文字符串加'u'和不加'u'**
加'u'表示Unicode编码,Unicode编码既包括utf-8,也包括ascii,未加u默认中文编码为'utf-8',加了u之后变成英文编码ascii;
In[12]: a='石油加工、炼焦及核燃料加工业'
In[13]: import chardet
In[14]: chardet.detect(a)
Out[14]: {'confidence': 0.99, 'encoding': 'utf-8'}
In[15]: a=u'石油加工、炼焦及核燃料加工业'
In[16]: chardet.detect(a)
Out[16]: {'confidence': 1.0, 'encoding': 'ascii'}
###############################################
**情况2 —— utf-8编码成ascii**
a='石油加工、炼焦及核燃料加工业',正常;
In[29]: chardet.detect(a)
Out[29]: {'confidence': 0.99, 'encoding': 'utf-8'}
In[30]: a.decode('utf-8')
Out[30]: u'\u77f3\u6cb9\u52a0\u5de5\u3001\u70bc\u7126\u53ca\u6838\u71c3\u6599\u52a0\u5de5\u4e1a'
In[31]: a
Out[31]: '\xe7\x9f\xb3\xe6\xb2\xb9\xe5\x8a\xa0\xe5\xb7\xa5\xe3\x80\x81\xe7\x82\xbc\xe7\x84\xa6\xe5\x8f\x8a\xe6\xa0\xb8\xe7\x87\x83\xe6\x96\x99\xe5\x8a\xa0\xe5\xb7\xa5\xe4\xb8\x9a'
In[32]: k1=a.decode('utf-8')
In[33]: k1
Out[33]: u'\u77f3\u6cb9\u52a0\u5de5\u3001\u70bc\u7126\u53ca\u6838\u71c3\u6599\u52a0\u5de5\u4e1a'
In[34]: chardet.detect(k1)
Out[34]: {'confidence': 1.0, 'encoding': 'ascii'}
可以看出,字符串默认是utf-8,或许是reload(sys),sys.setdefaultencoding('utf8')的原因,因此需要对其解码,用a.decode('utf-8'),a仍然不变,需要重新命名一个新的变量k1存储k1=a.decode('utf-8'),解码之后为ascii码;

k1.encode('utf-8')
Out[36]: '\xe7\x9f\xb3\xe6\xb2\xb9\xe5\x8a\xa0\xe5\xb7\xa5\xe3\x80\x81\xe7\x82\xbc\xe7\x84\xa6\xe5\x8f\x8a\xe6\xa0\xb8\xe7\x87\x83\xe6\x96\x99\xe5\x8a\xa0\xe5\xb7\xa5\xe4\xb8\x9a'

可以看出,将解码为ascii码的字符k1,重新编码成utf-8,k1.encode('utf-8'),是可以的;
######################
**情况3 —— ascii编码成utf-8  ,报错**
In[27]: a='石油加工、炼焦及核燃料加工业'
In[28]: a.encode('ascii')
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
    exec code_obj in self.user_global_ns, self.user_ns
  File "<ipython-input-28-bb580b290ae2>", line 1, in <module>
    a.encode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)
In[29]: chardet.detect(a)
Out[29]: {'confidence': 0.99, 'encoding': 'utf-8'}
可以看出:如果将utf-8编码的字符用ascii编码,会报如下错:UnicodeDecodeError;
###############################
总结:spark中csv读取中文编码默认是以英文字符读取的,即ascii编码;
**字符编码:对于中文字符的处理——将字符转换成str,再判断str是否是unicode编码,如果是再将其解码成ascii,**
def __check_the_encode(self, str1):
        if not isinstance(str1, str):
            str1 = str(str1)
        if not isinstance(str1, unicode):
            str1 = str1.decode('utf-8')
        return str1
为什么这样做能解决问题?
这样做目的是为了将行业代码编码统一,如果行业代码不是str那么强转为str,可以避免行业代码为0120这样的情况,转为str后为'120',又由于映射大小行业的字典中是这样的{'1':'120'},因此,其在编译环境下,通常将数字字符编码成ascii码,因此,需要进一步将上述str解码decode('utf-8')成ascii;
In[57]: chardet.detect(str1)
Out[57]: {'confidence': 1.0, 'encoding': 'ascii'}
In[58]: str1.decode('utf-8')
Out[58]: u'1'
In[59]: chardet.detect(str1)
Out[59]: {'confidence': 1.0, 'encoding': 'ascii'}

In[62]: str2='哈哈'
In[63]: chardet.detect(str2)
Out[63]: {'confidence': 0.7525, 'encoding': 'utf-8'}
In[64]: str2.decode('utf-8')
Out[64]: u'\u54c8\u54c8'
In[65]: chardet.detect(str2.decode('utf-8'))
Out[65]: {'confidence': 1.0, 'encoding': 'ascii'}


In[66]: str3 = 'num'
In[67]: chardet.detect(str3)
Out[67]: {'confidence': 1.0, 'encoding': 'ascii'}
In[68]: str3.decode('utf-8')
Out[68]: u'num'
In[69]: chardet.detect(str3)
Out[69]: {'confidence': 1.0, 'encoding': 'ascii'}
In[70]: str3.decode('ascii')
Out[70]: u'num'
In[71]: chardet.detect(str3)
Out[71]: {'confidence': 1.0, 'encoding': 'ascii'}


###############################
def hy_map_nan(big_hy_name):
    if big_hy_name in [u'石油加工、炼焦及核燃料加工业',u'电力、热力、燃气及水生产和供应业',u'化学原料及化学制品制造业',u'医药制造业和销售',
                       u'砖瓦、石材等建筑材料制造',u'广告业',u'批发和零售业',u'其它',u'综合',u'贸易、进出口',u'邮政业',u'其他商务服务业',
                       u'电气机械及器材制造业',u'水利管理业',u'管道运输业',u'专用化学产品制造',u'居民服务、修理和其他服务业',
                       u'人力资源服务',u'体育、娱乐业']:
        return 'nan'
    else:
        return big_hy_name

def shixin_risk_type(spark, sc):
    from pyspark.sql.functions import udf
    from pyspark.sql.types import StringType
    sqlContext = SQLContext(sparkContext=sc)
    # df1 = sqlContext.read.csv(readpath + 'new_update_hy_risk_rank_proportion.csv', header=True)
    df1 = sqlContext.read.csv(readpath + 'hy_chuli_shixin_db_dataset.csv', header=True)
    df1.show()
    df1.createOrReplaceTempView('b1')
    df12 = sqlContext.sql("select * from b1 where big_hy_name = '石油加工、炼焦及核燃料加工业'")
    df12.show()
    spark.stop()
    df1.createOrReplaceTempView('b1')
    df12=sqlContext.sql("select * from b1 order by big_hy_name")
    df12.show()
    spark.stop()
    df = sqlContext.read.csv(readpath + 'Orderby_shixin_decision_tree_prob_info.csv', header=True)
    risk_type_map = udf(prob_map_to_rank, StringType())
    bighy_map_nan = udf(hy_map_nan, StringType())
    df2 = df.withColumn("risk_type", risk_type_map(df['shixin_prob']))
    df3 = df2.withColumn("new_bighy_name", bighy_map_nan(df2['big_hy_name']))
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值