2017-06-09 12 views
2

私はMatlabユーザであり、Pythonに移行しようとしています。私はde2bi関数の最小限の例(Matlabで以前に持っていたPythonの十進数を右のmsbのようにバイナリに変換する)を記述しようとしました。しかし、私は愚かな配列と混同しています。整数と配列入力にnumpy配列を使用する

Pythonコード:

import numpy as np 

def de2bi(d, n) 
    d = np.array(d) 
    power = 2**np.arange(n) 
    d = d * np.ones((1,n)) 
    b = np.floor((d%(2*power))/power) 
    return b 

Pythonの出力:

>>> print(de2bi(13,8)) 
[[ 1. 0. 1. 1. 0. 0. 0. 0.]] 

print(de2bi([13,15],8)) #This line fails 

MATLABコード:

function b = d2b(d, n) 
    d = d(:); 
    power = ones(length(d), 1)*(2.^(0 : n-1)); 
    d = d * ones(1, n); 
    b = floor(rem(d, 2*power)./power); 
end 

Matlabの出力:

>> d2b(13,8) 

ans = 

    1  0  1  1  0  0  0  0 

>> d2b([13,15],8) 

ans = 

    1  0  1  1  0  0  0  0 
    1  1  1  1  0  0  0  0 

Matlabコードは整数入力と整数配列の両方で動作しています。しかし、Pythonコードは整数入力でも動作しますが、配列では失敗します。整数配列と整数配列の両方をPythonで自動的に管理する方法は?それは非常に簡単な質問かもしれませんが、私を許してください。しかし、私はPythonで非常に初心者です。

ありがとうございます。

+0

「flipud」の使用は面白く見えます。あなたは2dの配列を生成するために放送を利用して、matlabのようなnumpyの電源ラインを書くことができるはずです。 – hpaulj

+0

@hpaulj問題は、整数入力を使用しようとすると、Pythonは[x]のようなリストに変換せず、[x、y]の[[x、y]]のようなリストのリストに変わります私は手動でそれを変換します。私はxと[x]、[y]の[x、y]については[x]を得る必要があると思うが、matlabのようにコードの数行でこの簡単なステップを管理する方法を知らない。 – pythoner

答えて

0

これは役に立ちますか?

In [443]: power = 2**np.arange(8) 
In [444]: np.floor((d[:,None]%(2*power))/power) 
Out[444]: 
array([[ 1., 0., 1., 1., 0., 0., 0., 0.], 
     [ 1., 1., 1., 1., 0., 0., 0., 0.]]) 

powerに対するdを放送し、powerのディメンションの拡張が自動的に行われます:d[:,None]%(2*power[None,:])

In [439]: d=np.array([13,15]) 
In [440]: power=np.ones((d.shape[0],1))*(2**np.arange(8)) 
In [441]: power 
Out[441]: 
array([[ 1., 2., 4., 8., 16., 32., 64., 128.], 
     [ 1., 2., 4., 8., 16., 32., 64., 128.]]) 
In [442]: np.floor((d[:,None]%(2*power))/power) 
Out[442]: 
array([[ 1., 0., 1., 1., 0., 0., 0., 0.], 
     [ 1., 1., 1., 1., 0., 0., 0., 0.]]) 

私たちもonesを必要としません。 MATLABのonesは、(2,8)形状の配列と同じ次元展開を行います。

d=np.atleast_1d(d)で始めることができますので、1要素配列のようにスカラーのケースを扱います。スカラを与えられたときには1dの配列を返し、リストや1dの配列を与えたときには2dを返します。 MATLABではすべてが2d以上です。 dを展開する際に


いっそのこと、ellipsisを使用しています。次に、dは0d、1d、またはndでもかまいません。

np.floor((d[...,None]%(2*power))/power) 
+0

答えをありがとう。 'd = [13,15]'で動作しますが、 'd = np.atleast_1d(d)'を使った後でも、dが整数に直接 'd = 13'として代入されたときにIndexErrorを返します。 MATLABでは、整数xを自動的に配列[x]に変換するので、操作中に問題は発生しません。 – pythoner

+0

'np.floor((d [...、なし]%(2 * power))/ power'に関して編集していないとコメントしていますが、0d配列でも動作します。 – pythoner

+0

'atleast_1d'はスカラーで動作するはずですが、これを覚えておいてください。 MATLABにはスカラーはありません;すべてが2dです.1行のMATLABのケースにはshape(1,8)があり、numpyと同様に(8)になります。 – hpaulj

1

問題は乗算にあります:d = d * np.ones((1,n))です。 NumPyは要素ごとの乗算を実行しようとしますが、次元の不一致(1つの行には1つの行しかありません)が原因で失敗します。しかし、dがスカラーである場合、NumPyはスカラーに乗算することを意味すると推測できるため、コードが実行されます。

あなたが本当にやりたいことは(私が理解するように)各要素をn長の行に展開することです。可能な解決策は、配列のサイズが変更できないため、新しい値を保持する中間配列を作成することです。

def d2b(d, n): 
    d = np.array(d) 
    d = np.reshape(d, (1, -1)) 
    power = np.flipud(2**np.arange(n)) 

    g = np.zeros((np.shape(d)[1], n)) 

    for i, num in enumerate(d[0]): 
     g[i] = num * np.ones((1,n)) 
    b = np.floor((g%(2*power))/power) 
    return b 
+0

本当にループが必要ですか? numpyがループなしでこれを処理できる直接的な方法はありませんか? – pythoner

+0

スカラー配列の乗算に依然依存しているので、私は100%肯定的ではありません。たぶん場合は、配列配列の乗算(np.dot())に操作を回すことができますか?おそらく、1の代わりにアイデンティティ行列を使っているかもしれませんが、私はその数学については分かりません。 –

+0

答えをありがとう。私はmatlabでやっているようにループに入ることなく同じ操作を得る直接的な方法があると思います。私はちょうどPythonを学び始め、基礎を扱おうとしています。私は、ショートカットについても、他の回答を見ることを願っています。 (まだ十分な評判がないので、私はあなたに+1を与えることができません申し訳ありません) – pythoner

関連する問題