Since for the general case you are going to be returning a copy anyway, you may find yourself producing more readable code by using np.delete:
>>> a = np.arange(12).reshape(3, 4)
>>> np.delete(a, 2, axis=1)
array([[ 0, 1, 3],
[ 4, 5, 7],
[ 8, 9, 11]])
Answer from Jaime on Stack OverflowSince for the general case you are going to be returning a copy anyway, you may find yourself producing more readable code by using np.delete:
>>> a = np.arange(12).reshape(3, 4)
>>> np.delete(a, 2, axis=1)
array([[ 0, 1, 3],
[ 4, 5, 7],
[ 8, 9, 11]])
Use a slice that excludes the last element.
In [19]: a[:,:-1]
Out[19]:
array([[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
If you want something other than the last element I'd just build a list to select with.
In [20]: selector = [x for x in range(a.shape[1]) if x != 2]
In [21]: a[:, selector]
Out[21]:
array([[ 1, 2, 4],
[ 2, 4, 8],
[ 3, 6, 12]])
http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
When the columns are not a MultiIndex, df.columns is just an array of column names so you can do:
df.loc[:, df.columns != 'b']
a c d
0 0.561196 0.013768 0.772827
1 0.882641 0.615396 0.075381
2 0.368824 0.651378 0.397203
3 0.788730 0.568099 0.869127
Don't use ix. It's deprecated. The most readable and idiomatic way of doing this is df.drop():
>>> df.drop('b', axis=1)
a c d
0 0.418762 0.869203 0.972314
1 0.991058 0.594784 0.534366
2 0.407472 0.396664 0.894202
3 0.726168 0.324932 0.906575
Note that by default, .drop() does not operate inplace; despite the ominous name, df is unharmed by this process. If you want to permanently remove b from df, do df.drop('b', inplace=True).
df.drop() also accepts a list of labels, e.g. df.drop(['a', 'b'], axis=1) will drop column a and b. You can use columns too, as in df.drop(columns='a') or df.drop(columns=['a', 'b']) (thanks @BallpointBen in the comments).
You can just pass the players that you want to include as a list to the first index of score like this:
>>> import numpy as np
>>> score = np.array([
... [0,0,0,0],
... [1,2,1,1],
... [2,-6,0,2],
... [3,4,1,3]
... ])
>>> players_to_include = [0,2,3]
>>> score[players_to_include, 1]
array([ 0, -6, 4])
This will get you only player [0,2,3]'s score.
To generalize, you can do:
>>> players = list(xrange(np.size(score, 0)))
>>> players
[0, 1, 2, 3]
>>> excludes = [2,3]
>>> players_to_include = [p for p in players if p not in excludes]
>>> players_to_include
[0, 1]
>>> score[players_to_include, 1]
array([0, 2])
You can enter the range of requested rows as a list, for example:
score[ range(2) + [4], 1]
For a more general predicate function p(x) = 1 if x is a good row, you can do:
score [ [x for x in range(score.shape[0]) if p(x)], 1]
Since the result's buffer will have a gap, compared to the original, it will have to be a copy. I believe delete takes different approaches depending on the inputs.
One approach is a boolean index, e.g.
ind = np.ones((10,), bool)
ind[n] = False
A1 = A[ind,:]
Another is to do the equivalent with index values
ind = range(n) + range(n+1:A.shape[0]] # using list concatenate
A1 = A[ind,:]
And as you note, using that index with take may be faster than direct indexing. I doubt if the difference is big, but I haven't timed it recently.
ind could also made by concatenation of 1d arrays. Alternatively, index the two parts, and concatenate them:
np.concatenate([A[:n,:],A[n+1:],axis=0)
The inputs to concatenate are slices, but result is a copy.
np.r_[0:n, n+1:A.shape[0]]
is a convenient way of generating the integer index list - but not necessarily a speed solution.
Why is the difference time difference between a view and a copy significant? If you do it a few times in the program, it shouldn't matter. If you do this deletion repeatedly, I'd question the larger program design. Could, you for example, accumulate the deletion indices, and perform the deletion step just once?
A few timings:
In [17]: arr=np.arange(1000)
In [18]: timeit arr[np.r_[:500,501:1000]].shape
10000 loops, best of 3: 55.7 us per loop
In [19]: timeit arr.take(np.r_[:500,501:1000]).shape
10000 loops, best of 3: 44.2 us per loop
In [20]: timeit np.r_[:500,501:1000]
10000 loops, best of 3: 36.3 us per loop
In [23]: timeit ind=np.ones(arr.shape[0],bool);ind[500]=False;arr[ind].shape
100000 loops, best of 3: 12.8 us per loop
Oops, the boolean index is faster in this test case.
Best yet:
In [26]: timeit np.concatenate((arr[:500],arr[501:])).shape
100000 loops, best of 3: 4.61 us per loop
I was able to come up with a function that uses np.take that runs faster than the list method.
def index_rows_by_exclusion_nptake(arr, i):
"""
Return copy of arr excluding single row of position i using
numpy.take function
"""
return arr.take(range(i)+range(i+1,arr.shape[0]), axis=0)
%timeit index_rows_by_exclusion_nptake(x,1)
#The slowest run took 9.46 times longer than the fastest. This could mean that an intermediate result is being cached
#100000 loops, best of 3: 2.95 µs per loop
One way to get an R-like syntax here would be to use np.r_:
>>> Z = np.arange(2000).reshape(20, 100)
>>> Z.shape
(20, 100)
>>> x = Z[:,np.r_[:49,50:100]]
>>> x.shape
(20, 99)
>>> x[0,48:52]
array([48, 50, 51, 52])
and we see that the 50th column (with number 49) is missing from x.
This would work:
>>> a = np.arange(2000).reshape(20, 100)
>>> b = a[:, np.arange(a.shape[1]) != 50]
>>> b.shape
(20, 99)
You can use b = numpy.delete(a, indices, axis=0)
Source: NumPy docs.
You could try:
a = numpy.random.rand(100,200)
indices = numpy.random.randint(100,size=20)
b = a[np.setdiff1d(np.arange(100),indices),:]
This avoids creating the mask array of same size as your data in https://stackoverflow.com/a/21022753/865169. Note that this example creates a 2D array b instead of the flattened array in the latter answer.
A crude investigation of runtime vs memory cost of this approach vs https://stackoverflow.com/a/30273446/865169 seems to suggest that delete is faster while indexing with setdiff1d is much easier on memory consumption:
In [75]: %timeit b = np.delete(a, indices, axis=0)
The slowest run took 7.47 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 24.7 µs per loop
In [76]: %timeit c = a[np.setdiff1d(np.arange(100),indices),:]
10000 loops, best of 3: 48.4 µs per loop
In [77]: %memit b = np.delete(a, indices, axis=0)
peak memory: 52.27 MiB, increment: 0.85 MiB
In [78]: %memit c = a[np.setdiff1d(np.arange(100),indices),:]
peak memory: 52.39 MiB, increment: 0.12 MiB