table.loc[lambda df: df["column"].between(2, 3, inclusive="neither")]
this is useful when your dataframe has a long name, or when you have some long method chain and you need to subset at the end: table.foo().bar().baz().loc[lambda df: ...]it is still more verbose, but I actually prefer always providing column names as strings. it's more explicit. I don't like R's environment-manipulation metaprogramming magic where you can give column names as symbols.
as for resetting the index all the time, this is something of an antipattern. if you set up your index right beforehand it isn't necessary so often.
`table.query("column > 2 and column2 < 3")`
0: https://marketplace.visualstudio.com/items?itemName=ms-tools...
If you know the class of an object, let's say Class, but the object has yet to be "constructed" so that IPython can correctly infer its type, you can type `Class.[TAB]` in IPython and look at its methods.
For example, in Sympy, you have a matrix type called Matrix. You can do `(A * B).diagonalize()`, or alternatively you can do `Matrix.diagonalize(A * B)`, which has some advantages because doing `(A * B).[TAB]` does nothing useful because Python can't infer types.
You can also do the same for modules. `ModuleName.[TAB]`
To be honest though, I found the experience smoother in R for some reason.
My skin writhes every time I need to type:
table.loc[(table.column > 2) | (table.column2 < 3)].reset_index(drop=True)
when I want to subset a table.