Question: I found a piece of code I don't really understand. It basically goes like this:

```
array = np.ones((5, 4))*np.nan
s1 = pd.Series([1,4,0,4,5], index=[0,1,2,3,4])
I = s1 == 4
print(I)

0    False
1     True
2    False
3     True
4    False
dtype: bool

```

I really understand this part, it return a pd.Series of boolean with `True` at the indexes where 4 is. Now, the author uses `I` to index `array`:

```
array[I,0] = 3
array[I,1] = 7
array[I,2] = 2
array[I,3] = 5
print(array)

[[  3.   7.   2.   5.]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]
 [ nan  nan  nan  nan]
 [ nan  nan  nan  nan]]

```

The new `array` makes no sense to me, I would like to return instead:

```
[[ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]]

```

Can someone explain what is happening here, and how I can change the code above to return what I need?

Answer: 
The explanation lies in the fact that `numpy` array and `pandas` series treat the *logic index* differently. The former treat `True` as 1 and `False` as 0 while latter pick up the value where the logic is `True` and drop the value where the logic is `False`. As a demonstration:

```
import numpy as np
import pandas as pd

arr = np.array([1,2,3,4,5])
arr                           # this is a numpy array 
array([1, 2, 3, 4, 5])
arr[[True, False, True]]
array([2, 1, 2])              # check here how it is actually picking the value at position 
                              # 1 and 0 alternatively;

ser = pd.Series([1,2,3,4,5])
ser                           # this is a pandas Series
0    1
1    2
2    3
3    4
4    5
dtype: int64
ser[[True, False, True]]      # in pandas Series, it will pick up values where the logic is True;
0    1
2    3
dtype: int64

```

You see how they behave differently. Since your `array` is a numpy array, we can not use the logic index to pick up the value. In order to get the result you intended, we can try to extract the index of the true value from `I` and then use it on your `array`:

```
array[I[I == True].index,0] = 3
array[I[I == True].index,1] = 7
array[I[I == True].index,2] = 2
array[I[I == True].index,3] = 5
print(array)

[[ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]]

```
Its a mistake. I don't know exactly how numpy is interpreting `I` in the index. But I'm pretty sure this is what was intended:

```
array[I.values, 0] = 3
array[I.values, 1] = 7
array[I.values, 2] = 2
array[I.values, 3] = 5
print(array)

[[ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]
 [  3.   7.   2.   5.]
 [ nan  nan  nan  nan]]

```