1

I have two lists, namely;

x = [3, 7, 9, ...] and y = [13, 17, 19, ...]

And I have a dataframe like this:

df =
    x   y   z   
0   0   10  0.54
1   1   11  0.68
2   2   12  0.75
3   3   13  0.23
4   4   14  0.52
5   5   15  0.14
6   6   16  0.23
.   .    .  .. 
.   .    .  ..

What I want to do is slice the dataframe given the pairwise combos in an efficient manner, as so:

df_slice = df [ ( (df.x == x[0]) & (df.y == y[0]) ) |
                ( (df.x == x[1]) & (df.y == y[0]) ) |
                ....
                ( (df.x == x[-1) & (df.y == y[-1]) ) ]


df_slice =
    x   y   z   
3   3   13  0.23
7   7   17  0.74
9   9   19  0.24
.  ..   ..  ....

Is there any way to do this programmatically and quickly?

Landmaster
  • 1,043
  • 2
  • 13
  • 21

1 Answers1

0

Create helper DataFrame and DataFrame.merge with no on parameter, so merging by all intersected columns, here by x and y:

x = [3, 7, 9]
y = [13, 17, 19]

df1 = pd.DataFrame({'x':x, 'y':y})

df2 = df.merge(df1)
print (df2)
   x   y
0  3  13

Or get interesection of MultiIndexes by Index.isin and filter by boolean indexing:

mux = pd.MultiIndex.from_arrays([x, y])

df2 = df[df.set_index(['x','y']).index.isin(mux)]
print (df2)
   x   y
3  3  13

Your solution should be changed with list comprehension of zipped lists and np.logical_or.reduce:

mask = np.logical_or.reduce([(df.x == a) & (df.y == b) for a, b in zip(x, y)])
df2 = df[mask]
print (df2)
   x   y     z
3  3  13  0.23
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252