30

I am trying to take the following R statement and convert it to Python using NumPy:

1 + apply(tmp,1,function(x) length(which(x[1:k] < x[k+1])))

Is there a Python equivalent to which()? Here, x is row in matrix tmp, and k corresponds to the number of columns in another matrix.

Previously, I tried the following Python code, and received a Value Error (operands could not be broadcast together with shapes):

for row in tmp:
        print np.where(tmp[tmp[:,range(k)] < tmp[:,k]])
Bokononisms
  • 349
  • 1
  • 3
  • 8
  • you are scripting `tmp` twice.. do you mean to use `row` instead inside the loop? – Doboy Aug 31 '12 at 00:15
  • Where does your `k` come from? What shape is your `tmp`? – Pierre GM Aug 31 '12 at 00:29
  • OK for this example, but this question may be extended to a multidimensional boolean array in which you want the index of 'True' values – Manu H Apr 01 '16 at 09:05
  • 2
    That's some pretty obfuscated R code for "the number of previous elements which were < x[k+1]. We don't even need the inefficient `length(which(...))`, we only need to directly sum the Booleans `sum(x[1:k] < x[k+1])`. – smci Nov 27 '16 at 17:34
  • Related question [Pandas Equivalent of R's which()](http://stackoverflow.com/questions/25086060/pandas-equivalent-of-rs-which) – smci Nov 27 '16 at 17:35
  • After looking for the question asked here, I'm finding that this and related posts don't actually answer it. `which()` compares a vector against a condition and returns a vector of the indices which meet it. I think [this post](https://stackoverflow.com/questions/21800169/python-pandas-get-index-of-rows-which-column-matches-certain-value) answers the literal question asked here. – Hendy Aug 27 '17 at 16:42

3 Answers3

6
    >>> which = lambda lst:list(np.where(lst)[0])

    Example:
    >>> lst = map(lambda x:x<5, range(10))
    >>> lst
    [True, True, True, True, True, False, False, False, False, False]
    >>> which(lst)
    [0, 1, 2, 3, 4]
Vishal Mishra
  • 71
  • 1
  • 1
  • 4
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – andreas Oct 17 '16 at 22:40
4

The Python code below answers my question:

np.array([1 + np.sum(row[range(k)] < row[k]) for row in tmp])

Here tmp is a 2d array, and k is a variable which was set for column comparison.

Thanks to https://stackoverflow.com/users/601095/doboy for inspiring me with the answer!

Community
  • 1
  • 1
Bokononisms
  • 349
  • 1
  • 3
  • 8
1

From http://effbot.org/zone/python-list.htm:

To get the index for all matching items, you can use a loop, and pass in a start index:

i = -1
try:
    while 1:
        i = L.index(value, i+1)
        print "match at", i
except ValueError:
    pass
Timothy P. Jurka
  • 918
  • 1
  • 11
  • 21
  • 19
    This is simpler and more readable `matchings_indices = [ i for i, x in enumerate(x) if x == value ]` – Doboy Aug 31 '12 at 00:16