如何将“字节”对象转换为 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 中的文字字符串?的主要内容,如果未能解决你的问题,请参考以下文章
在 Pandas 中为 DataFrame 中的每一行返回多行
将 pandas 数据帧转换为 json 对象 - pandas