Reputation: 81
I want to print numpy arrays nicer, using the indices into the array [0 1]
indexes row zero and column one:
Suppose we have a big numpy array
x = np.arange(400*8000).reshape(400,8000).astype(float)
Now we want to print row 100, but only the last ten entries:
print x[100, -10:]
This should result in something like:
Index | X
[ 100 7990] | 807990
[ 100 7991] | 807991
[ 100 7992] | 807992
[ 100 7993] | 807993
[ 100 7994] | 807994
[ 100 7995] | 807995
[ 100 7996] | 807996
[ 100 7997] | 807997
[ 100 7998] | 807998
[ 100 7999] | 807999
I produced this by getting the index as follows:
index = np.indices(X.shape)[:, 100, -10:]
print index
# array([[ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
# [7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999]])
But this seems to be very inefficient, especially, when the indexing gets more complicated, or X
gets bigger (As in billions of entries).
Is there a better way of creating index arrays from an index (here the index is [100, -10:]
and the index array is index
)?
Upvotes: 2
Views: 470
Reputation: 734
numpy.ix is very useful tool in indexing problems. To get necessary slice from matrix you have to do following:
x = np.arange(400*8000).reshape(400,8000).astype(float)
print x[np.ix_(np.tile(np.array([100]), 10), np.arange(7990, 8000))]
where you pass np.ix function as index. You have to pass sequences of rows and columns as arguments for np.ix() function. In this example it is [100, 100, ..., 100] for rows and [7990, 7991, ..., 7999] for columns. If you try to print array return by np.ix as
print np.ix_(np.tile(np.array([100]), 10), np.arange(7990, 8000))
You will see that it returns
(array([[100],
[100],
[100],
[100],
[100],
[100],
[100],
[100],
[100],
[100]]), array([[7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999]]))
where first value of first array intersects with first value of the second array and so on, to slice your matrix properly. If you need more dimensions, just add extra parameters to your np.ix function, where first parameter is row sequence, second is column sequence, third is depth sequence and so on. For example:np.ix(np.arange(0,3), np.arange(3,8), np.arange(4,2,-1))
which will return slicing array which slices first 3 rows, from 3rd to 7th columns and from 4th to 3rd pages your matrix. See some examples here.
Upvotes: 1
Reputation: 1044
Creating index arrays is just a matter of math. You don't need a tricky built in function for this. The following function, for example, should suit you just fine and will run in no time at all.
def getIndices(x, row, lastNCols):
"""
x = your matrix
row = the index of the row you want (100 in your case)
lastNCols = the number of columns you want to grab off the end of that
row (10 in your case)
"""
rows = np.full(lastNCols, row, dtype=int32)
cols = np.arange(x.shape[1] - lastNCols, x.shape[1], dtype=int32)
return np.column_stack((rows, cols)).T
Run:
x = np.arange(400*8000).reshape(400,8000).astype(float)
getIndices(x, 100, 10)
Output:
array([[ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
[7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999]])
Upvotes: 2