看起来为空的字符串,长度却是1?

这一篇放在NLP下面 但其实与机器学习/神经网络没啥关系,不过广义上看 也是在"自然语言处理"中遇到的问题..

linux下 发现一些奇怪的问题,看起来为空的字符串,长度却是1:

控制台运行的部分代码如下:

my_list = []
[my_list.append(x) for line in qfl_df['text'] for x in jieba.cut(line) if len(x) == 1]
my_counter = Counter(my_list) 
print(my_counter.most_common())

 ('觉', 1),
 ('颠', 1),
 ('彘', 1),
 ('魋', 1),
 ('节', 1),
 ('饩', 1),
 ('粟', 1),
 ('殆', 1),
 ('', 1),
 ('抚', 1),
 ('尊', 1),
 ('匹', 1),
 ('宅', 1),
 ('璞', 1),
 ('石', 1),
 ('蜃', 1),
 ('蛤', 1),
 ('羇', 1),
 ('縻', 1),
 ('坑', 1),
 ('抑', 1),
 ('庞', 1),
 ('涓', 1),
 ('殊', 1),
 ('柬', 1),
 ('畎', 1),
 ('亩', 1),
 ('闺', 1),
 ('', 1),
 ('佃', 1),
 ('伏', 1),
 ('单', 1),
而再打印my_counter中这些看起来为空的字符的长度, 长度确实为1而不是0.. 也奇怪,还可以有多个..

找到其中一条被cut的句子, 某行x:  line = qfl_df['text'][x: x+1].text.values.tolist()[0]
print(line) 从打印信息上看出错的行表面上是: '楚季者、王子敖之曾孙也。蚠冒主章者,王子无钧也。令尹孙叔敖者、章之子也。左司马戍者、庄王之曾孙也。叶公诸梁者、戍之第三弟也。楚大夫申无畏者,又氏文氏。\n
jieba.lcut(line)的结果 看起来是正常的, 不会出现似空非空的东西
这一段话的原文是: '楚季者、王子敖之曾孙也。蚠冒主蒍章者,王子无钧也。令尹孙叔敖者、蒍章之子也。左司马戍者、庄王之曾孙也。叶公诸梁者、戍之第三弟也。楚大夫申无畏者,又氏文氏。\n'
我做了繁简转换后,记录对应关系,后期只使用简体的line:

line = zhconv.convert(origi_line, 'zh-hans')
[print(x,x.encode(), "AAAA") for x in line]


楚 b'\xe6\xa5\x9a' AAAA
季 b'\xe5\xad\xa3' AAAA
者 b'\xe8\x80\x85' AAAA
、 b'\xe3\x80\x81' AAAA
王 b'\xe7\x8e\x8b' AAAA
子 b'\xe5\xad\x90' AAAA
敖 b'\xe6\x95\x96' AAAA
之 b'\xe4\xb9\x8b' AAAA
曾 b'\xe6\x9b\xbe' AAAA
孙 b'\xe5\xad\x99' AAAA
也 b'\xe4\xb9\x9f' AAAA
。 b'\xe3\x80\x82' AAAA
蚠 b'\xe8\x9a\xa0' AAAA
冒 b'\xe5\x86\x92' AAAA
主 b'\xe4\xb8\xbb' AAAA
 b'\xf0\xab\x87\xad' AAAA
章 b'\xe7\xab\xa0' AAAA
者 b'\xe8\x80\x85' AAAA
, b'\xef\xbc\x8c' AAAA
王 b'\xe7\x8e\x8b' AAAA
子 b'\xe5\xad\x90' AAAA
无 b'\xe6\x97\xa0' AAAA
钧 b'\xe9\x92\xa7' AAAA
也 b'\xe4\xb9\x9f' AAAA
。 b'\xe3\x80\x82' AAAA
令 b'\xe4\xbb\xa4' AAAA
尹 b'\xe5\xb0\xb9' AAAA
孙 b'\xe5\xad\x99' AAAA
叔 b'\xe5\x8f\x94' AAAA
敖 b'\xe6\x95\x96' AAAA
者 b'\xe8\x80\x85' AAAA
、 b'\xe3\x80\x81' AAAA
 b'\xf0\xab\x87\xad' AAAA
章 b'\xe7\xab\xa0' AAAA
之 b'\xe4\xb9\x8b' AAAA
子 b'\xe5\xad\x90' AAAA
也 b'\xe4\xb9\x9f' AAAA
。 b'\xe3\x80\x82' AAAA
左 b'\xe5\xb7\xa6' AAAA
司 b'\xe5\x8f\xb8' AAAA
马 b'\xe9\xa9\xac' AAAA
戍 b'\xe6\x88\x8d' AAAA
者 b'\xe8\x80\x85' AAAA
、 b'\xe3\x80\x81' AAAA
庄 b'\xe5\xba\x84' AAAA
王 b'\xe7\x8e\x8b' AAAA
之 b'\xe4\xb9\x8b' AAAA
曾 b'\xe6\x9b\xbe' AAAA
孙 b'\xe5\xad\x99' AAAA
也 b'\xe4\xb9\x9f' AAAA
。 b'\xe3\x80\x82' AAAA
叶 b'\xe5\x8f\xb6' AAAA
公 b'\xe5\x85\xac' AAAA
诸 b'\xe8\xaf\xb8' AAAA
梁 b'\xe6\xa2\x81' AAAA
者 b'\xe8\x80\x85' AAAA
、 b'\xe3\x80\x81' AAAA
戍 b'\xe6\x88\x8d' AAAA
之 b'\xe4\xb9\x8b' AAAA
第 b'\xe7\xac\xac' AAAA
三 b'\xe4\xb8\x89' AAAA
弟 b'\xe5\xbc\x9f' AAAA
也 b'\xe4\xb9\x9f' AAAA
。 b'\xe3\x80\x82' AAAA
楚 b'\xe6\xa5\x9a' AAAA
大 b'\xe5\xa4\xa7' AAAA
夫 b'\xe5\xa4\xab' AAAA
申 b'\xe7\x94\xb3' AAAA
无 b'\xe6\x97\xa0' AAAA
畏 b'\xe7\x95\x8f' AAAA
者 b'\xe8\x80\x85' AAAA
, b'\xef\xbc\x8c' AAAA
又 b'\xe5\x8f\x88' AAAA
氏 b'\xe6\xb0\x8f' AAAA
文 b'\xe6\x96\x87' AAAA
氏 b'\xe6\xb0\x8f' AAAA
。 b'\xe3\x80\x82' AAAA

 b'\n' AAAA 
 终于抓到了几个    b'\xf0\xab\x87\xad'   b'\xf0\xab\x93\xa7' 这样的字符   好像decode转换不了成正常的中文: 

In [1]:  b'\xf0\xab\x93\xa7'.decode()
Out[1]: ''

In [2]:  b'\xf0\xab\x93\xa7'.decode('gbk')
Out[2]: '皤摟'

In [3]:  b'\xf0\xab\x93\xa7'.decode('gb2312')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
 in 
----> 1 b'\xf0\xab\x93\xa7'.decode('gb2312')

UnicodeDecodeError: 'gb2312' codec can't decode byte 0x93 in position 2: illegal multibyte sequence

 试试 b'\xf0\xab\x93\xa7'.decode('gbk') 的结果是 '皤摟', 仍然不符合预期


刚开始以为是 zhconv 这个库不行,又换了一个opencc来转换, 还是同样的问题。那去源码看看/打印: 
opencc中 关键的self._dict_chain_data 打印结果部分如下 
'葯': '药',
'葷': '荤',
'蒍': '',
'蒐': '搜',
'蒓': '莼',
'蒔': '莳',
'蒕': '蒀',
'蒙': '蒙',
'蒞': '莅',
'蒭': '',
'蒼': '苍',
'蓀': '荪',
'蓆': '席',
'蓋': '盖',
'蓧': '',
'蓮': '莲',
'蓯': '苁',
'蓴': '莼',
'蓽': '荜',
 
 这个转换关系 是在字典中的, 比如上面的来自这个文件 opencc\dictionary\TSCharacters.txt :(windows下用notpad打开看到):
葤    荮
葦    苇
葯    药
葷    荤
蒍    
蒐    搜
蒓    莼
蒔    莳
蒕    蒀
蒙    蒙
蒞    莅
蒭    
蒼    苍
蓀    荪
蓆    席
蓋    盖
蓧    
蓮    莲
蓯    苁
蓴    莼
蓽    荜
 

 '楚季者、王子敖之曾孙也。蚠冒主章者,王子无钧也。'   这句话在windows中可以正常复制粘贴,但粘贴到linux下就会报错 或 看起来自动省略 字(至少我手上的centos/ubuntu多台机器都是这样)
 
看起来为空的字符串,长度却是1?_第1张图片

 问题大概找到了:应该是这些繁体字对应的简体字的编码问题。


 Windows的默认编码为GBK,Linux的默认编码为UTF-8。在Windows下编辑的中文,在Linux下显示为乱码。 看到有文章 为了解决此问题,修改Linux的默认编码为GBK。 但我觉得好像强制直接修改不太合适。
有一种不太合适的临时解决方法 可能是 在windows而不是linux运行。

 linux下:

In [41]: ' '.join(jieba.cut(origi_line))
Out[41]: '楚季者 、 王子 敖 之 曾孙 也 。 蚠 冒主 蒍 章者 , 王子 无钧 也 。 令尹 孙叔敖 者 、 蒍 章 之子 也 。 左 司马 戍者 、 庄王 之 曾孙 也 。 叶公 诸梁者 、 戍 之 第三 弟 也 。 楚 大夫 申 无畏 者 , 又 氏 文氏 。 \n'

In [42]: ' '.join(jieba.cut(line))
Out[42]: '楚季者 、 王子 敖 之 曾孙 也 。 蚠 冒主  章者 , 王子 无钧 也 。 令尹 孙叔敖 者 、  章之子 也 。 左 司马 戍者 、 庄王 之 曾孙 也 。 叶公 诸梁者 、 戍 之 第三 弟 也 。 楚 大夫 申 无畏 者 , 又 氏 文氏 。 \n'

 win下:

 ' '.join(jieba.cut(origi_line))
Out[13]: '楚季者 、 王子 敖 之 曾孙 也 。 蚠 冒主 蒍 章者 , 王子 无钧 也 。 令尹 孙叔敖 者 、 蒍 章 之子 也 。 左 司马 戍者 、 庄王 之 曾孙 也 。 叶公 诸梁者 、 戍 之 第三 弟 也 。 楚 大夫 申 无畏 者 , 又 氏 文氏 。 \n'
' '.join(jieba.cut(line))
Out[14]: '楚季者 、 王子 敖 之 曾孙 也 。 蚠 冒主  章者 , 王子 无钧 也 。 令尹 孙叔敖 者 、  章之子 也 。 左 司马 戍者 、 庄王 之 曾孙 也 。 叶公 诸梁者 、 戍 之 第三 弟 也 。 楚 大夫 申 无畏 者 , 又 氏 文氏 。 \n'

  

还搜到 ideographic description characters相关,在linux下 可能能用这样的转换替代? 这个还得再花些时间研究下


搜了很多 后来又想到,这个问题 其实产生的影响: 从人的角度看  可读性不太好。   但好像对程序运行,对于我想要的计算结果 影响比较小。
 比如计算词频时,对于这样的字 程序仍然会正常占位计算。 会影响jieba.cut,  但这样的字  可能比较难(机率较小)会组成一个词组, 所以实际影响结果  也还好。可以作为遗留问题将来跟进,不阻塞当前的工作。

 

你可能感兴趣的:(NLP,nlp,python)