จะถอดรหัสอาร์เรย์ / สตริงที่เข้ารหัสใน Python3 ได้อย่างไร AttributeError: วัตถุ 'numpy.ndarray' ไม่มีแอตทริบิวต์ 'ถอดรหัส'

ใน Python 3 ฉันมีอาร์เรย์ NumPy ดังต่อไปนี้เป็น strings

string แต่ละตัวในอาร์เรย์ NumPy จะอยู่ในรูปแบบ b'MD18EE แทนที่จะเป็น MD18EE

ตัวอย่างเช่น:

import numpy as np
print(array1)
(b'first_element', b'element',...)

โดยปกติแล้ว เราจะใช้ .decode('UTF-8') เพื่อถอดรหัสองค์ประกอบเหล่านี้

อย่างไรก็ตาม ถ้าฉันลอง:

array1 = array1.decode('UTF-8')

ฉันได้รับข้อผิดพลาดต่อไปนี้:

AttributeError: 'numpy.ndarray' object has no attribute 'decode'

ฉันจะถอดรหัสองค์ประกอบเหล่านี้จากอาร์เรย์ NumPy ได้อย่างไร (นั่นคือฉันไม่ต้องการ b'')

แก้ไข:

สมมติว่าฉันกำลังจัดการกับ Pandas DataFrame โดยมีเพียงบางคอลัมน์เท่านั้นที่ถูกเข้ารหัสในลักษณะนี้ ตัวอย่างเช่น:

import pandas as pd
df = pd.DataFrame(...)

df
        COL1          ....
0   b'entry1'         ...
1   b'entry2'
2   b'entry3'
3   b'entry4'
4   b'entry5'
5   b'entry6'

person ShanZhengYang    schedule 02.11.2016    source แหล่งที่มา


คำตอบ (2)


คุณมีอาร์เรย์ของสตริงไบต์ ประเภทคือ S:

In [338]: arr=np.array((b'first_element', b'element'))
In [339]: arr
Out[339]: 
array([b'first_element', b'element'], 
      dtype='|S13')

astype แปลงเป็น Unicode ได้อย่างง่ายดาย ซึ่งเป็นประเภทสตริงเริ่มต้นสำหรับ Py3

In [340]: arr.astype('U13')
Out[340]: 
array(['first_element', 'element'], 
      dtype='<U13')

นอกจากนี้ยังมีไลบรารีของฟังก์ชันสตริง - การนำเมธอด str ที่สอดคล้องกันไปใช้กับองค์ประกอบของอาร์เรย์สตริง

In [341]: np.char.decode(arr)
Out[341]: 
array(['first_element', 'element'], 
      dtype='<U13')

astype นั้นเร็วกว่า แต่ decode ให้คุณระบุการเข้ารหัสได้

ดูเพิ่มเติมที่ วิธีถอดรหัสอาร์เรย์ numpy ของ dtype=numpy .string_?

person hpaulj    schedule 03.11.2016

หากคุณต้องการให้ผลลัพธ์เป็นรายการสตริง (Python) คุณสามารถใช้ list comprehension ได้:

>>> l = [el.decode('UTF-8') for el in array1]
>>> print(l)
['element', 'element 2']
>>> print(type(l))
<class 'list'>

หรือคุณสามารถใช้ np.vectorize เพื่อสร้างฟังก์ชันตัวถอดรหัสแบบเวกเตอร์ได้:

>>> decoder = np.vectorize(lambda x: x.decode('UTF-8'))
>>> array2 = decoder(array1)
>>> print(array2)
['element' 'element 2']
>>> print(type(array2))
<class 'numpy.ndarray'>
person Wander Nauta    schedule 02.11.2016
comment
ขอบคุณ! ฉันกำลังนำอาร์เรย์ numpy และวางลงใน dataframe ของ pandas อาจมีทางลัดที่เร็วกว่านี้? แปลงตามคอลัมน์? - person ShanZhengYang; 02.11.2016
comment
คุณหมายถึงเร็วกว่าใน 'ทำงานเร็วขึ้น' หรือเร็วกว่าใน 'โค้ดน้อยลง'? เนื่องจากทั้งสองวิธีเป็นแบบ oneliners คำสั่ง print จึงเป็นเพียงการแสดงว่ามันใช้งานได้ :) - person Wander Nauta; 02.11.2016
comment
:) ฉันคิดว่าวิ่งเร็วขึ้น อย่างไรก็ตาม ฉันคิดว่าวิธีนี้ใช้ได้ผลดี---ดูเหมือนว่าจะเป็นผลข้างเคียงของ Python2/Python3 ดังนั้นฉันจึงสงสัยว่ามีผู้อื่นประสบปัญหานี้ - person ShanZhengYang; 02.11.2016
comment
ไม่ว่าในแง่ใดก็ตาม การใช้ decoder ทำให้ฉันเกิดข้อผิดพลาดนี้: AttributeError: 'numpy.void' object has no attribute 'decode' - person ShanZhengYang; 02.11.2016
comment
อืม ในกรณีนี้ ดูเหมือนว่าอาร์เรย์ของคุณไม่ใช่อาร์เรย์ของสตริง แต่เป็นอาร์เรย์ของสตริงและ voids - แต่ฉันแน่ใจว่าคุณจะสามารถแก้ไขตัวถอดรหัสเพื่อจัดการสิ่งเหล่านั้นได้เช่นกัน อย่างไรก็ตาม ฉันคิดว่าวิธีที่ดีที่สุด (และอาจเร็วที่สุด) ในการเข้าถึงสิ่งนี้คือให้แน่ใจว่าคุณใช้สตริงทุกที่ แทนที่จะเป็นไบต์ วิธีที่คุณจะทำเช่นนั้นขึ้นอยู่กับว่าข้อมูลของคุณมาจากไหนและคุณอ่านข้อมูลอย่างไร - person Wander Nauta; 02.11.2016
comment
คุณจะถอดรหัสเฉพาะสิ่งที่เป็นไบต์และเพิกเฉยต่อช่องว่าง: lambda x: x.decode('UTF-8') if isinstance(x, bytes) else x อย่างไรก็ตาม อย่างที่ฉันบอกไป จะดีกว่าถ้าจัดการกับที่อื่น - person Wander Nauta; 03.11.2016
comment
np.void อาจเป็นบันทึกจากอาร์เรย์ที่มีโครงสร้าง ซึ่งเป็นสารประกอบ dtype dtype ของอาร์เรย์ของคุณคืออะไร - person hpaulj; 03.11.2016