Hướng dẫn utf 16 python - trăn utf 16

Tôi đang cố đọc một tệp văn bản vào Python, nhưng dường như nó sử dụng một số mã hóa rất lạ. Tôi thử thông thường:

file = open('data.txt','r')

lines = file.readlines()

for line in lines[0:1]:
    print line,
    print line.split()

Đầu ra:

0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']

In dòng hoạt động tốt, nhưng sau khi tôi cố gắng chia dòng để tôi có thể chuyển đổi nó thành một chiếc phao, nó trông thật điên rồ. Tất nhiên, khi tôi cố gắng chuyển đổi các chuỗi đó thành phao, điều này tạo ra một lỗi. Bất kỳ ý tưởng về cách tôi có thể chuyển đổi chúng trở lại thành số?

Tôi đặt DataFile mẫu ở đây nếu bạn muốn thử tải nó: https://dl.dropboxusercontent.com/u/3816350/posts/data.txt

Tôi chỉ muốn sử dụng numpy.loadtxt hoặc numpy.genfromtxt, nhưng họ cũng không muốn đối phó với tệp điên rồ này.

Hỏi ngày 11 tháng 10 năm 2013 lúc 23:45Oct 11, 2013 at 23:45

Hướng dẫn utf 16 python - trăn utf 16

DanhicksteindanhicksteinDanHickstein

6.29612 Huy hiệu vàng 50 Huy hiệu bạc86 Huy hiệu đồng12 gold badges50 silver badges86 bronze badges

5

Tôi sẵn sàng đặt cược đây là một tệp UTF-16-le và bạn đang đọc nó như bất kỳ mã hóa mặc định nào của bạn.

Trong UTF-16, mỗi ký tự có hai byte.* Nếu các ký tự của bạn là ASCII, điều này có nghĩa là mã hóa UTF-16 trông giống như mã hóa ASCII với thêm '\ x00' sau mỗi ký tự.

Để khắc phục điều này, chỉ cần giải mã dữ liệu:

print line.decode('utf-16-le').split()

Hoặc làm điều tương tự ở cấp độ tệp với mô -đun IO hoặc Codecs:

file = io.open('data.txt','r', encoding='utf-16-le')

* Đây là một chút của quá trình đơn giản hóa: mỗi ký tự BMP có hai byte; Mỗi ký tự không BMP được biến thành một cặp thay thế, với mỗi hai người thay thế lấy hai byte. Nhưng có lẽ bạn không quan tâm đến những chi tiết này.

Đã trả lời ngày 11 tháng 10 năm 2013 lúc 23:50Oct 11, 2013 at 23:50

ABARNERTABARNERTabarnert

340K43 Huy hiệu vàng571 Huy hiệu bạc648 Huy hiệu Đồng43 gold badges571 silver badges648 bronze badges

7

Có vẻ như UTF-16 đối với tôi.

>>> test_utf16 = '0\x00.\x000\x002\x000\x000\x001\x009\x007\x00'
>>> test_utf16.decode('utf-16')
u'0.0200197'

Bạn có thể làm việc trực tiếp với chuỗi Unicode:

>>> float(test_utf16)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: null byte in argument for float()
>>> float(test_utf16.decode('utf-16'))
0.020019700000000001

Hoặc mã hóa chúng thành một cái gì đó khác biệt, nếu bạn thích:

>>> float(test_utf16.decode('utf-16').encode('ascii'))
0.020019700000000001

Lưu ý rằng bạn cần phải làm điều này càng sớm càng tốt trong quá trình xử lý của bạn. Như nhận xét của bạn đã lưu ý, split sẽ hoạt động không chính xác trên biểu mẫu được mã hóa UTF-16. Biểu diễn UTF-16 của ký tự không gian

0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']
0 là
0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']
1, do đó split loại bỏ khoảng trắng nhưng rời khỏi byte null.

Thư viện 2.6 và sau đó

0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']
3 có thể xử lý việc này cho bạn, cũng như thư viện
0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']
4 cũ.
0.0200197   1.97691e-005

['0\x00.\x000\x002\x000\x000\x001\x009\x007\x00', '\x001\x00.\x009\x007\x006\x009\x001\x00e\x00-\x000\x000\x005\x00']
3 Xử lý LineFeed tốt hơn, vì vậy nó tốt hơn nếu có.

Đã trả lời ngày 11 tháng 10 năm 2013 lúc 23:48Oct 11, 2013 at 23:48

Peter DeGlopperPeter DeglopperPeter DeGlopper

35K7 Huy hiệu vàng87 Huy hiệu bạc82 Huy hiệu đồng7 gold badges87 silver badges82 bronze badges

2

Đây thực sự chỉ là đề xuất của @Abarnert, nhưng tôi muốn đăng nó như một câu trả lời vì đây là giải pháp đơn giản nhất và là giải pháp mà tôi đã kết thúc bằng cách sử dụng:

    file = io.open(filename,'r',encoding='utf-16-le')
    data = np.loadtxt(file,skiprows=8)

Điều này cho thấy cách bạn có thể tạo một đối tượng tệp bằng io.open bằng cách sử dụng bất kỳ mã hóa điên rồ nào mà tệp của bạn xảy ra, sau đó chuyển đối tượng tệp đó cho np.loadtxt (hoặc np.genfromtxt) để tải nhanh và dễ dàng.

Đã trả lời ngày 3 tháng 9 năm 2015 lúc 15:41Sep 3, 2015 at 15:41

DanhicksteindanhicksteinDanHickstein

6.29612 Huy hiệu vàng 50 Huy hiệu bạc86 Huy hiệu đồng12 gold badges50 silver badges86 bronze badges

Tôi sẵn sàng đặt cược đây là một tệp UTF-16-le và bạn đang đọc nó như bất kỳ mã hóa mặc định nào của bạn.

file_handle=open(file_name,'rb')
file_first_line=file_handle.readline()
file_handle.close()
print file_first_line
if '\x00' in file_first_line:
    file_first_line=file_first_line.replace('\x00','')
    print file_first_line

Trong UTF-16, mỗi ký tự có hai byte.* Nếu các ký tự của bạn là ASCII, điều này có nghĩa là mã hóa UTF-16 trông giống như mã hóa ASCII với thêm '\ x00' sau mỗi ký tự.

Để khắc phục điều này, chỉ cần giải mã dữ liệu:Jan 31, 2017 at 12:09

0

Hoặc làm điều tương tự ở cấp độ tệp với mô -đun IO hoặc Codecs: