2016-11-07 15 views
1

私はブール値から10進数および実数までの値を持つnumpy配列を持っています。私はこのデータをデータベースから取得します。フィールドが見つからないときは0を返します。すべてのゼロを-1に、Falsesを0に、Truesを1に変更したいと思います。しかし、PythonではPythonのnumpyが0に変更され、Falseが-1に変更されない

X[X==0] = -1 
X[X==False] = 0 
X[X==True] =1 

結果がすべてゼロであり、すべてFalses両方-1に変更され:偽と0との間の区別は、従ってこれは私が試みているものであり、1の両方が変化します。どうすればこの問題を解決できますか?

編集: これは私の配列のサンプルです:

[[0.03829744 0.0 True False True True 6.0] 
[0.0 0.0 True False True True 6.0] 
[0.09174341 0.0 True False True True 6.0] 
[0.03489284 2 0 True True False 0 6.0]] 

私はすべての偽の値が0であることを、すべての真の値が1

であることを、-1であることを、すべての0.0の値を望みます

編集2:すべての値を超えるループは動作しますが、それらが均一である場合

for i in xrange(X.shape[0]): 
    for j in xrange(X.shape[1]): 
     if X[i,j] == 0.0 and type(X[i, j]) == float: 
      X[i][j] = -1 
+2

'np.array'には同じタイプのデータしか含まれていません。したがって、 'int'を' bool'とすると 'bool'を' int'にキャストします – MMF

+0

[Python:False vs 0]の可能な複製(http://stackoverflow.com/questions/27431249/python -false-vs-0) – SiHa

+0

@SiHaこれは素晴らしいリンクですが、このナンシー問題にはあまり関係ありません。 –

答えて

3

numpyのアレイが最も効率的である、または彼らは一定のTYを持って、少なくとも場合は、よりエレガントな解決策が存在しなければなりませんそれらに関連するパターン。値の配列をdtype=objectのnumpyの配列で保持することができますが、これはおそらくnumpyで行うのが最も効率的ではありません。

これに対応して、各要素の型にアクセスできる効率的な(ネイティブnumpy)メソッド(私が知っている)はありません。これは単にnumpyを使用するときに通常起こるものではありません。

私はあなたのコードをよりエレガントにするために考えることができる唯一の方法は、ダブルループを関数呼び出しに変換することです。私はmapを使用しますが、これはネイティブのnumpy関数(これはC言語でコンパイルされるため)はまだ高速ではありませんが、おそらくPythonの二重ループより速く、より明確です。

あなたの例データは長方形ではありません。すなわち、2dのnumpy配列に変換することはできませんが、試してみると難しいです。私はあなたがMCVEをまとめる際に間違いを犯したと仮定し、サンプルデータの4行目から1つの要素を削除しました(その結果、配列(4,7)の形になります)。

import numpy as np 

# dummy data as nested list, make sure it's rectangular 
datlist = [[0.03829744, 0.0, True, False, True, True, 6.0], 
      [0.0, 0.0, True, False, True, True, 6.0], 
      [0.09174341, 0.0, True, False, True, True, 6.0], 
      [0.03489284, 0, True, True, False, 0, 6.0]] #dropped an element here 

# create a numpy array of dtype object from datlist 
dat = np.array(datlist,dtype=object) 

私は、これがあなたの出発点であるとあなたの例から集めました。さて、私は、配列の要素の値と型をチェックし、非boolのゼロについて-1を返す関数を定義します。

def zeroswap(elem): 
    # replace non-bool zeros with -1, leave the rest alone 
    return -1 if elem==0 and elem is not False else elem 

dat.ravel()[:] = list(map(zeroswap,dat.ravel())) #list() needed for python3 

結果の配列は次のようになります:

array([[0.03829744, -1, True, False, True, True, 6.0], 
     [-1, -1, True, False, True, True, 6.0], 
     [0.09174341, -1, True, False, True, True, 6.0], 
     [0.03489284, -1, True, True, False, -1, 6.0]], dtype=object) 

ご覧のとおり、フロートの両方と、この関数は、全体のデータ範囲にアクセスするために.ravel()を利用して、あなたの配列にmap PEDすることができ整数のゼロは-1に変換されました。これは私には意味をなさないものです。それは、Falseのゼロ以外をチェックしたことによるものです。 2種類の数値の零点を区別したい場合は、zeroswap関数で簡単に行うことができます。 bool値を切り替える場合は、その値を変更することもできます。ここで0.0 -> -10 -> -1False -> 0True -> 1other -> otherを変えていく、アップグレード機能です:

def zeroswap(elem): 
    if type(elem) is bool: 
     return int(elem) 
    elif elem==0: 
     return -1 
    else: 
     return elem 

あなたはそれはあなたがそれを行うことを期待していることを確認するために、様々な要素にこの関数を呼び出して遊ぶことができます。結論としては、配列の次元数を知らなくても操作できるように、配列の階段状のバージョンに対してmapの機能が必要です。

関連する問題