Python: автоматически выбрать подходящий размер типа данных (int) - PullRequest
5 голосов
/ 19 декабря 2011

Я выделяю (возможно, большую) матрицу нулей с помощью Python и numpy. Я планирую поместить в него целые числа без знака от 1 до N.

N довольно разнообразно: может легко варьироваться от 1 до миллиона, возможно, даже больше.

Я знаю N до инициализации матрицы. Как я могу выбрать тип данных моей матрицы так, чтобы я знал, что она может содержать (без знака) целые числа размером N?

Кроме того, я хочу выбрать наименьший такой тип данных, который подойдет.

Например, если бы N было 1000, я бы выбрал np.dtype('uint16'). Если N равно 240, uint16 будет работать, но uint8 также будет работать и является наименьшим типом данных, который я могу использовать для хранения чисел.

Так я инициализирую массив. Я ищу SOMETHING_DEPENDING_ON_N:

import numpy as np
# N is known by some other calculation.
lbls = np.zeros( (10,20), dtype=np.dtype( SOMETHING_DEPENDING_ON_N ) )

ура!

Aha!

Только что реализованный numpy v1.6.0 + имеет np.min_scalar_type, документацию . D'о! (хотя ответы все еще полезны, потому что у меня нет 1.6.0).

Ответы [ 3 ]

2 голосов
/ 19 декабря 2011

Как насчет написания простой функции для выполнения работы?

import numpy as np

def type_chooser(N):
    for dtype in [np.uint8, np.uint16, np.uint32, np.uint64]:
        if N <= dtype(-1):
            return dtype
    raise Exception('{} is really big!'.format(N))

Пример использования:

>>> type_chooser(255)
<type 'numpy.uint8'>
>>> type_chooser(256)
<type 'numpy.uint16'>
>>> type_chooser(18446744073709551615)
<type 'numpy.uint64'>
>>> type_chooser(18446744073709551616)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "spam.py", line 6, in type_chooser
    raise Exception('{} is really big!'.format(N))
Exception: 18446744073709551616 is really big!
2 голосов
/ 19 декабря 2011

Создайте отображение максимального значения для ввода, а затем найдите наименьшее значение, большее, чем N.

typemap = {
  256: uint8,
  65536: uint16,
   ...
}

return typemap.get(min((x for x in typemap.iterkeys() if x > N)))
0 голосов
/ 19 декабря 2011

Для интереса, вот версия, с которой я играл, пока @Ignacio Vazquez-Abrams и @wim не опубликовали свои ответы, используя сдвиги:

def minimal_uint_type(N):
    bases = [8,16,32,64]
    a = [N>>i for i in bases]
    try: dtype = bases[len(np.nonzero(a)[0])]
    except: raise StandardError('{} is really big!'.format(N))
    return dtype
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...