【问题标题】:How to convert/decode a pandas.Series of mixed bytes/strings into string or utf-8如何将 pandas.Series 混合字节/字符串转换/解码为字符串或 utf-8
【发布时间】:2019-12-13 03:06:10
【问题描述】:

我想在两种可能的情况下解决问题:

  1. 我不知道字符串系列是 UTF-8 还是预先字节。

  2. pd.Series 中的字符串是混合字节和 `UTF-8/。

我猜这会有相同的解决方案。

目前为:

b = pd.Series(['123', '434,', 'fgd', 'aas', b'442321'])
b.str.decode('utf-8')

给出NaNs 字符串已经在UTF-8 中的位置。或者它们是自动 ASCII 码?我可以在decode 中给出error 参数,以便字符串在它已经在UTF-8 中的地方保持“未解码”吗?文档字符串似乎没有提供太多信息。

或者有没有更好的方法来实现这一点?

或者,在 pandas 中是否有类似 .str.decode 的字符串方法,当字符串为 bytes 或 UTF-8 时,它只返回 True/False?

编辑:

我能想到的一个选择是:

b = pd.Series(['123', '434,', 'fgd', 'aas', b'442321'])
converted = b.str.decode('utf-8')
b.loc[~converted.isnull()] = converted

这是推荐的方式吗?好像有点绕。我想更优雅的方法实际上只是一种检查 str 是否是 Series 的所有元素上的字节并在这种情况下返回布尔数组的方法。

【问题讨论】:

    标签: python python-3.x pandas utf-8


    【解决方案1】:

    对于大型系列来说,这肯定会减慢速度,但您可以通过可调用对象传递三元表达式:

    >>> b.apply(lambda x: x.decode('utf-8') if isinstance(x, bytes) else x)                                                                                                                                                                                      
    0       123
    1      434,
    2       fgd
    3       aas
    4    442321
    dtype: object
    

    查看.str.decode() 的源代码是有益的——它只是将_na_map(f, arr) 应用于系列,其中函数f 是f = lambda x: x.decode(encoding, errors)。因为str 开始时没有“解码”方法,所以该错误将变为 NaN。这发生在str_decode()。

    >>> from pandas.core.strings import str_decode                                                                                                                                                                                                               
    >>> from pandas.core.strings import _cpython_optimized_encoders                                                                                                                                                                                              
    
    >>> "utf-8" in _cpython_optimized_encoders                                                                                                                                                                                                                   
    True
    >>> str_decode(b, "utf-8")                                                                                                                                                                                                                                   
    array([nan, nan, nan, nan, '442321'], dtype=object)
    
    >>> from pandas.core.strings import _na_map                                                                                                                                                                                                                  
    >>> f = lambda x: x.decode("utf-8")                                                                                                                                                                                                                          
    >>> _na_map(f, b)                                                                                                                                                                                                                                            
    array([nan, nan, nan, nan, '442321'], dtype=object)
    

    【讨论】:

      【解决方案2】:

      问题还在git中解决

      线路造成的

        except (TypeError, AttributeError):
               return na_value
      

      修复添加fillna

      b.str.decode('utf-8').fillna(b)
      Out[237]: 
      0       123
      1      434,
      2       fgd
      3       aas
      4    442321
      dtype: object
      

      【讨论】:

      • 唯一的事情是这将掩盖由于编码引起的实际错误。如果您有无法解码为 Utf-8 的 Latin-1 字节,则在可能无意中将其替换为原始字节。
      • 感谢您的回答,两者都非常有启发性和有用性,我不知道该接受哪个。还要感谢您提出 git 问题,它看起来确实很有用。
      猜你喜欢
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2010-09-21
      • 1970-01-01
      相关资源
      最近更新 更多