LINUX.ORG.RU

Печать массивов numpy в двоичном и шестнадцатиричном виде

 ,


0

1

Имеется массив numpy. Для определённости dtype=[('name', 'S14'), ('offset', '<u4'), ('size', '<u4'), ('flags', '<u4')]

Требуется вывести его на экран так, чтобы первые 3 поля вывелись как bytes и 2 32-битных целых с ведущими пробелами, а последнее — как числа по основанию 2 или 16 с ведущими нулями.

Как это сделать? Или хотя бы как называется нужная мне фича в терминологии numpy?

Ответ:

def r26_to_str(x):
    name, offset, size, flags = x
    return name.decode() + f' {offset:8} {size:8} {flags:0{8}x}'
    #return name.decode() + f' {offset:8} {size:8} {flags:0{32}b}'

np.vectorize(r26_to_str)(file_list)
★★★★★

Последнее исправление: question4 (всего исправлений: 1)

Это выглядит тем, что нужно. Если там нет, то, боюсь, только ручками.
Можно еще в PyPI порыться на наличие таких либ для удобного вывода, не подумал сразу.
Upd.: array2string выглядит подходяще, потому что можно задать словарь с функциями для формата данных.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 2)
Ответ на: комментарий от adn

tobites

В смысле tobytes?

tobytes и unpackbits

Как применить их только к 1 полю из 4, выведя одновременно все 4?

question4 ★★★★★
() автор топика
Ответ на: комментарий от Virtuos86

array2string выглядит подходяще, потому что можно задать словарь с функциями для формата данных.

Словарь принимает только названия типов вроде 'int' или групп типов. Способ задать для отдельного поля я не нашёл. Плохо искал?

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

У тебя же 3 поля одного типа. Обрабатываться они будут последовательно, так? Напиши функцию, которая для первых 2-х вызовов будет работать по одному алгоритму, а для 3-го — по другому. Хак, но рабочий. Я бы так сделал.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

выглядит тем, что нужно

А есть двоичный редактор? Допустим файл - ни что иное, как массив флагов.

anonymous
()
Ответ на: комментарий от anonymous

выглядит тем, что нужно

А есть двоичный редактор? Допустим файл - ни что иное, как массив флагов.

А где у ТС файл?

Я вообще не шарю в NumPy :). Но если человек спрашивает, как распечатать массив NumPy, то логично предложить ему средства, которые предлагает для этого сам NumPy. Если есть более идиоматичный или практичный способ, я не против.

Virtuos86 ★★★★★
()
xs = np.array([(b'asdf\x15', 2, 3, 0xAB), (b'asdfg', 2, 3, 0xFFFFFFFF) ], dtype=[('name', 'S14'), ('offset', '<u4'), ('size', '<u4'), ('unknown', '<u4')])

def to_str(x):
    name, offset, size, unknown = x
    return f"{name} {offset} {size} {unknown:0{8}x}"

for x in np.vectorize(to_str)(xs):
    print(x)

# b'asdf\x15' 2 3 000000ab
# b'asdfg' 2 3 ffffffff

Если я правильно понял

Требуется вывести его на экран так, чтобы первые 3 поля вывелись как bytes и 2 32-битных целых, а последнее — как числа по основанию 2 или 16 с ведущими нулями.

Лучше бы пример привёл, а то нихрена не понятно.

fulmar_lor
()
Ответ на: комментарий от fulmar_lor

Если я правильно понял

Ты всё правильно понял. Спасибо.

Только я не учёл, что десятичные числа тоже нужно подгонять по ширине. Поэтому:

def to_str(x):                 
    name, offset, size, unknown = x
    return f"{name} {offset:8} {size:8} {unknown:0{8}x}"

np.vectorize(to_str)(filellist)
array(["b'\\x00INDEX   .CTR'     8188      380 7b4d1947",
       "b'\\x00SPLIT2  .PC8'     8568     5155 5a82194e",
....
       "b'\\x00MONTH   .PC8'  3686922     4405 8770194c"], dtype='<U46')

Для двоичных надо {unknown:0{32}x}.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Для двоичных надо {unknown:0{32}x}.

Конечно же {unknown:0{32}b}.

question4 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.