Repository: pandas-dev/pandas
Pull request: ASV: used integer ndarray as indexer for Series.take indexing benchmark
- [x] closes #18000
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`

Series.take was using a list of booleans as indexers. Now, It is replaced with a random list of integers.
Here are the benchmark results with `asv run --bench indexing.Take`
### Benchmarks Results:

#### Before:

```
[100.00%] ··· indexing.Take.time_take                                                                                                                                                ok
[100.00%] ··· ========== =============
                index                 
              ---------- -------------
                 int      4.13±0.08ms 
               datetime   4.13±0.01ms 
              ========== =============
```

#### After:

```
[100.00%] ··· indexing.Take.time_take                                                                                                                                                ok
[100.00%] ··· ========== =============
                index                 
              ---------- -------------
                 int      6.36±0.08ms 
               datetime   6.29±0.03ms 
              ========== =============
```

Problem statement:
BENCH: Index.take benchmark is measuring wrong thing
The `take` benchmarks `indexing.IndexingMethods.time_take_intindex` is benchmarking `take` on a boolean list, which take interprets as a [0, 1, 0, 1, ...] values, which is a bit silly to benchmark. 
We should add some actual benchmark on integers instead.

Hints from issue discussion:
@jorisvandenbossche  I would like to make this issue to be my first contribution. I have looked at the source code and ready to take it up. 
Although I have unable to see as to why and how  a Boolean list <code>self.indexer </code> is  interpreted as integer [0,1,0,1,...] values?
Is it possible to resolve this issue by creating a new indexer list like <code>self.int_indexer</code> for benchmarking? What do you have in mind?

> Is it possible to resolve this issue by creating a new indexer list like self.int_indexer for benchmarking? What do you have in mind?

Yes, although I think you can just replace the existing `self.indexer` with a new list of ints instead of bools (we don't need to keep the old bench of using booleans).

> Although I have unable to see as to why and how a Boolean list self.indexer is interpreted as integer [0,1,0,1,...] values?

If you try to run the code (or similar), you will see:

```
In [84]: s = pd.Series(range(5))

In [85]: s.take([True, False, True, False, True])
Out[85]: 
1    1
0    0
1    1
0    0
1    1
dtype: int64

In [86]: s.loc[[True, False, True, False, True]]
Out[86]: 
0    0
2    2
4    4
dtype: int64
```

so take interprets the True, False as 0, 1  and not as a mask (like is done in `loc`)
@jorisvandenbossche I made the following changes in `indexing.IndexingMethods.time_take_intindex` 

Replaced the boolean list `indexer` with randomized integer list
`self.indexer = list(np.random.randint(0, 100000, size=100000))`
Does this resolve the issue? 

Also where should I add Tests? Should I add/modify any tests? 

It seems like the issue has been open for quite a while. I looked into the `take` benchmark, It is still using boolean values as `indexer`. Does not seem like anyone is working on the issue, I will quickly fix that.
take

Commit message: ASV: used integer list as indexer for series.take

Patch to review:
diff --git a/asv_bench/benchmarks/indexing.py b/asv_bench/benchmarks/indexing.py
index 836d3ca8602ec..a1466a7ad83ec 100644
--- a/asv_bench/benchmarks/indexing.py
+++ b/asv_bench/benchmarks/indexing.py
@@ -191,7 +191,7 @@ def setup(self, index):
         }
         index = indexes[index]
         self.s = Series(np.random.rand(N), index=index)
-        self.indexer = [True, False, True, True, False] * 20000
+        self.indexer = list(np.random.randint(0, N, size=N))
 
     def time_take(self, index):
         self.s.take(self.indexer)


Code review comments:
diff_hunk: @@ -191,7 +191,7 @@ def setup(self, index):
         }
         index = indexes[index]
         self.s = Series(np.random.rand(N), index=index)
-        self.indexer = [True, False, True, True, False] * 20000
+        self.indexer = list(np.random.randint(0, N, size=N))
path: asv_bench/benchmarks/indexing.py
text: @user1:
```suggestion
        self.indexer = np.random.randint(0, N, size=N)
```

(I would leave out the list here, then the focus is more on the actual take algorithm, and not on converting the list to an ndarray)

@author:
oh, Yeah! that makes sense. I will update the PR accordingly.