如何将“字节”对象转换为 Pandas Dataframe、Python3.x 中的文字字符串?

Posted

技术标签:

【中文标题】如何将“字节”对象转换为 Pandas Dataframe、Python3.x 中的文字字符串?【英文标题】:How to translate "bytes" objects into literal strings in pandas Dataframe, Python3.x? 【发布时间】:2017-03-16 08:16:44 【问题描述】:

我有一个 Python3.x pandas DataFrame,其中某些列是用字节表示的字符串(如在 Python2.x 中)

import pandas as pd
df = pd.DataFrame(...)
df
       COLUMN1         ....
0      b'abcde'        ....
1      b'dog'          ....
2      b'cat1'         ....
3      b'bird1'        ....
4      b'elephant1'    ....

当我使用df.COLUMN1 按列访问时,我看到Name: COLUMN1, dtype: object

但是,如果我按元素访问,它是一个“字节”对象

df.COLUMN1.ix[0].dtype
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'bytes' object has no attribute 'dtype'

如何将这些转换为“常规”字符串?也就是说,我怎样才能摆脱这个b'' 前缀?

【问题讨论】:

【参考方案1】:

您可以使用向量化的str.decode 将字节字符串解码为普通字符串:

df['COLUMN1'].str.decode("utf-8")

要对多个列执行此操作,您可以只选择 str 列:

str_df = df.select_dtypes([np.object])

全部转换:

str_df = str_df.stack().str.decode('utf-8').unstack()

然后您可以将转换后的 cols 替换为原始 df cols:

for col in str_df:
    df[col] = str_df[col]

【讨论】:

我遇到了同样的问题,但是我的数据框包含其他不是字节的 np 对象(数组,即 )。有没有办法只设置字节列?【参考方案2】:

结合@EdChum 和@Yu Zhou 的答案,一个更简单的解决方案是:

for col, dtype in df.dtypes.items():
    if dtype == np.object:  # Only process byte object columns.
        df[col] = df[col].apply(lambda x: x.decode("utf-8"))

【讨论】:

申请不是这里的路。使用df[col].str.decode('utf-8')【参考方案3】:

我添加了一些列在数据帧中充满 str 或混合 str 和字节的问题。通过对@Christabella Irwanto 提供的解决方案进行微小修改即可解决:(我更喜欢@Mad Physicist 建议的str.decode('utf-8')

for col, dtype in df.dtypes.items():
        if dtype == np.object:  # Only process object columns.
            # decode, or return original value if decode return Nan
            df[col] = df[col].str.decode('utf-8').fillna(df[col]) 


>>> df[col]
0        Element
1     b'Element'
2         b'165'
3            165
4             25
5             25

>>> df[col].str.decode('utf-8').fillna(df[col])
0     Element
1     Element
2         165
3         165
4          25
5          25
6          25

【讨论】:

【参考方案4】:

我在尝试解决同样的问题时遇到了这个线程,但更普遍的是,对于一个系列,其中一些值的类型为 str,其他类型为 bytes。从早期的解决方案中,我实现了这种选择性解码,如下所示,产生了一个系列,其所有值的类型都是str。 (python 3.6.9, 熊猫 1.0.5)

>>> import pandas as pd
>>> ser = pd.Series(["value_1".encode("utf-8"), "value_2"])
>>> ser.values
array([b'value_1', 'value_2'], dtype=object)
>>> ser2 = ser.str.decode("utf-8")
>>> ser[~ser2.isna()] = ser2
>>> ser.values
array(['value_1', 'value_2'], dtype=object)

对于这个用例,也许存在更方便/更高效的单线?起初我认为将“错误”kwarg 传递给 str.decode 会有一些价值,但我没有找到记录。

编辑:一个人绝对可以在一行中实现相同的效果,但我认为这样做的方式大约需要 25%(针对长度为 10^4 和 10^6 的系列进行测试),但大概不会复制。例如:

ser[ser.apply(type) == bytes] = ser.str.decode("utf-8")

【讨论】:

【参考方案5】:
df['COLUMN1'].apply(lambda x: x.decode("utf-8"))

【讨论】:

您好,欢迎来到 SO。多一点文字会很好。 ;-)

以上是关于如何将“字节”对象转换为 Pandas Dataframe、Python3.x 中的文字字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何将字节数据转换为 python pandas 数据框?

在 Pandas 中为 DataFrame 中的每一行返回多行

将 pandas 数据帧转换为 json 对象 - pandas

如何将 Pandas 数据框中的负数替换为零

如何将数据从 Scikit-learn Bunch 对象转换为 Pandas DataFrame?

将对象列表转换为 pandas 数据框