11

is there a way to pass array-range as argument to function ? Something like :

> blah(ary,arg1=1:5)

def blah(ary,arg1): print ary[arg1]
1
  • 4
    slice(1, 5) is what you're looking for. Commented Feb 22, 2015 at 0:15

4 Answers 4

9

Python accepts the 1:5 syntax only within square brackets. The interpreter converts it into a slice object. The __getitem__ method of the object then applies the slice.

Look at numpy/lib/index_tricks.py for some functions that take advantage of this. Actually they aren't functions, but rather classes that define their own __getitem__ methods. That file may give you ideas.

But if you aren't up to that, then possibilities include:

blah(arr, slice(1, 5))
blah(arr, np.r_[1:5])

nd_grid, mgrid, ogrid extend the 'slice' concept to accept an imaginary 'step' value:

mgrid[-1:1:5j]
# array([-1. , -0.5,  0. ,  0.5,  1. ])

Just be aware that anything which expands on a slice before passing it to your blah function, won't know about the shape of the other argument. So np.r_[:-1] just returns [].

And None can be used in slice: e.g. slice(None,None,-1) is equivalent of [::-1].

Sign up to request clarification or add additional context in comments.

1 Comment

How do I check if the argument I received is slice() vs ordinary number ? I got it isinstance(x,slice)
7

You can use the slice function

>>> def blah(ary,arg1):
...     print ary[arg1]
>>> blah(range(10), slice(1, 5))
[1, 2, 3, 4]

Comments

1

you can try like this:

def blah(ary, arg):
    arg = map(int, arg.split(":"))
    print ary[arg[0]:arg[1]]

blah([1,2,3,4,5,6],"2:5")

output:

[3, 4, 5]

Comments

0

Just saw it happen today and I thought it was curious, notice that they are passing the argument test_idx as a plain range

plot_decision_regions(X=X_combined_std, y=y_combined,
                      classifier=ppn, test_idx=range(105, 150))

So what does this do in the end?

Using it to slice a Numpy Array

ndarray[range(105, 150), :]

However when I test this by copying the ndarray value, instantiate it and try to slice it myself (basically makes a list instead) it won't allow me to pass that range on the slice it seems.

[[ 0.73088538 1.57698181], [ 0.17316034 0.1348488 ]]

which I extracted/copied from an ndarray when you click to set new value

erick = [[ 0.73088538 1.57698181], [ 0.17316034 0.1348488 ]]

-- SyntaxError. invalid syntax

had to put the commas to be accepted as a syntax and instantiates it as a list obj

erick = [[ 0.73088538, 1.57698181], [ 0.17316034, 0.1348488 ]]

erick[:]

(works, returning whole thing)

erick[range(0, 1), :]

-- TypeError. list indices must be integrers or slices, not tuple

(breaks, we tested that slicing works before so it has to do with the range)

enter image description here

Try again with a homebrew Numpy Array (spoiler, it works)

erickNpa = np.asarray(erick, dtype=np.float32)
erickNpa[range(0, 1), :]

enter image description here


Conclussion

You can pass range as arguments as seen on the first part, at some point the code wasn't executing but that had to do with the nature of what it was doing (using it to slice a list), however with the right scaffolding everything seems to work as proved when using a Numpy Array instead.



Sample Code

I will also put the function def in case the git gets taken down even tho I linked the line.

def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):

    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], 
                    y=X[y == cl, 1],
                    alpha=0.8, 
                    c=colors[idx],
                    marker=markers[idx], 
                    label=cl, 
                    edgecolor='black')

    # highlight test examples
    if test_idx:
        # plot all examples
        X_test, y_test = X[test_idx, :], y[test_idx]

        plt.scatter(X_test[:, 0],
                    X_test[:, 1],
                    c='',
                    edgecolor='black',
                    alpha=1.0,
                    linewidth=1,
                    marker='o',
                    s=100, 
                    label='test set')


# Training a perceptron model using the standardized training data:



X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))

plot_decision_regions(X=X_combined_std, y=y_combined,
                      classifier=ppn, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')

plt.tight_layout()
#plt.savefig('images/03_01.png', dpi=300)
plt.show()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.