Python:適切なデータ型のサイズ(int)を自動的に選択する

私はPythonとnumpyで0の(おそらく大)行列を割り当てています。私は符号なし整数を1から N に入れようと計画しています。

N is quite variable: could easily range from 1 all the way up to a million, perhaps even more.

行列の初期化の前に 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 ) )

乾杯!

ああ!

numpy v1.6.0 +には、 np.min_scalar_type ドキュメントをご覧ください。 D'oh! (私は1.6.0を持っていないので答えはまだ有用ですが)。

5
適切な int dtype( int32 )を取得するために、 np.array([N]).dtype > int64 )、 uint が好きです。
追加された 著者 mathematical.coffee,
適切な uint8 dtypeを取得するには、 np.array([N])。astype( 'uint')/b>は uint32 で始まります。例えば、 np.array([54])。astype( 'uint')はdtypeの uint32 を返しますが、 uint8 unsigned integerを最大54個まで保持できる最小型です。
追加された 著者 mathematical.coffee,
'uint' float のような基本的なdtypeを使用している場合、Numpyはシステムのデフォルトを使用しているので、 uint32 。デフォルト以外のサイズを取得するには、サイズを明示的に指定する必要があります。
追加された 著者 dtlussier,

3 答え

仕事をするための単純な関数を書くのはどうですか?

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

使用例:

>>> type_chooser(255)

>>> type_chooser(256)

>>> type_chooser(18446744073709551615)

>>> type_chooser(18446744073709551616)
Traceback (most recent call last):
  File "", line 1, in 
  File "spam.py", line 6, in type_chooser
    raise StandardError('{} is really big!'.format(N))
StandardError: 18446744073709551616 is really big!
2
追加された
本当に巧妙になりたいなら、 np.log2(N)を使って実装できます!
追加された 著者 wim,
ああ、これは私が後にしたものだった。私はビットシフトを使って自分のバージョンを考え出しましたが、基本的にあなたと同じです。乾杯
追加された 著者 mathematical.coffee,

入力する最大値のマッピングを作成し、Nより大きい最小値を探します。

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

return typemap.get(min((x for x in typemap.iterkeys() if x > N)))
2
追加された
乾杯!あなたのアプローチが本質的に同じであることは分かっていますが、私はdictを作っている私に依存していなかったので、私は@ wim'sと走りました。
追加された 著者 mathematical.coffee,
ディクテーションは実際にはここでは使用されていません。 2タプルのタプルを簡単に使うことができます。
追加された 著者 Karl Knechtel,

興味深いことに、@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
0
追加された