2017-12-13 11 views
0

ベクトル化された演算を効率的なコードに使用して、配列をスライスするなどの異なるサイズの配列に対して操作を行いたいと思います。しかし、私はそのようなn個の行を持っているだけでなく、平坦なnumpy配列で計算を行うことができるように関数を調整したいと思います。この例では単純な数値を使用していますが、プロジェクトで乱数生成を使用します。現在、形状に応じてスライスを区別するためにifステートメントを使用して解決しました。 if文がないと効率的な方法がありますか?形状の異なる配列のベクトル化された関数

import numpy as np 

def func(a, b, c, d): 
    if len(a.shape) == 1: 
     cf = -c 
     cf[:len(b)] += a - b 
     cf[-len(d)] -= d 
    else: 
     cf = -c 
     cf[:, :b.shape[1]] += a - b 
     cf[:, -d.shape[1]:] -= d 
    return cf 


a = np.array([1, 1, 1, 1, 1, 1, 1]) 
b = np.array([2, 2, 2, 2, 2, 2, 2]) 
c = np.array([3, 3, 3, 3, 3, 3, 3, 3]) 
d = np.array([4]) 
func(a, b, c, d) 

n = 10 
a = np.zeros((n, 7))+1 
b = np.zeros((n, 7))+2 
c = np.zeros((n, 8))+3 
d = np.zeros((n, 1))+4 
func(a, b, c, d) 

私はここでスライスの普遍的な方法を見つけていない可能性がありますか?

答えて

4

このコードは機能します。

def func(a, b, c, d): 
    cf = -c 
    cf[..., :b.shape[-1]] += a - b 
    cf[..., -d.shape[-1]:] -= d 
    return cf 

テスト:

## Test 1 
a = np.array([1, 1, 1, 1, 1, 1, 1]) 
b = np.array([2, 2, 2, 2, 2, 2, 2]) 
c = np.array([3, 3, 3, 3, 3, 3, 3, 3]) 
d = np.array([4]) 
func(a, b, c, d) 
""" 
array([-4, -4, -4, -4, -4, -4, -4, -7]) 
""" 

## Test 2 
n = 2 
a = np.zeros((n, 7))+1 
b = np.zeros((n, 7))+2 
c = np.zeros((n, 8))+3 
d = np.zeros((n, 1))+4 
func(a, b, c, d) 
""" 
array([[-4., -4., -4., -4., -4., -4., -4., -7.], 
     [-4., -4., -4., -4., -4., -4., -4., -7.]]) 
""" 
素晴らしい作品
+0

、ありがとう!あなたは何のための短い説明を与えることができますか? – Peterhack

+0

x [...、 - 1]:省略記号(...)は、x.ndimと同じ長さの選択タプルを作るのに必要なオブジェクトの数に展開されます。 – Silencer

+0

ありがとうございました!関数は最も効率的な方法で記述されていますか? – Peterhack