I think these would be better as abstract base classes rather than functions, specifically because it would make them easier to reuse throughout the codebase.  For example, if I want to check if something is a DataFrame or Series, I need to write `is_series(obj) or is_dataframe(obj)` and so on if it needs to cover more. It feels cleaner to be able to say something like `isinstance(obj, (SeriesLike, FrameLike))` and makes it easier to mix with list, tuple, etc... i.e. `isinstance(obj, (SeriesLike, FrameLike, tuple, list))`, which I think is cleaner. There's definitely a better name to be used here than `SeriesLike`, but this could end up being a class that has a method like:

```python
class SeriesLike(object):
    def __instancecheck__(cls, inst):
        return getattr(obj, '_typ', None) == 'series'
```

That said, this does not add any actual power or more streamlined code. It might make code easier to read and (potentially?) make it clearer how to subclass the objects.

Downside: I'm assuming these methods would be relatively easy to cythonize as compared to a custom class, so they could potentially be faster. That said, I'd guess that instance checks happen less frequently, so probably not a bottleneck.