Like a dict, a DataFrame's index is backed by a hash table. Looking up rows based on index values is like looking up dict values based on a key.
In contrast, the values in a column are like values in a list.
Looking up rows based on index values is faster than looking up rows based on column values.
For example, consider
df = pd.DataFrame({'foo':np.random.random(), 'index':range(10000)})
df_with_index = df.set_index(['index'])
Here is how you could look up any row where the df['index'] column equals 999.
Pandas has to loop through every value in the column to find the ones equal to 999.
df[df['index'] == 999]
# foo index
# 999 0.375489 999
Here is how you could lookup any row where the index equals 999. With an index, Pandas uses the hash value to find the rows:
df_with_index.loc[999]
# foo 0.375489
# index 999.000000
# Name: 999, dtype: float64
Looking up rows by index is much faster than looking up rows by column value:
In [254]: %timeit df[df['index'] == 999]
1000 loops, best of 3: 368 µs per loop
In [255]: %timeit df_with_index.loc[999]
10000 loops, best of 3: 57.7 µs per loop
Note however, it takes time to build the index:
In [220]: %timeit df.set_index(['index'])
1000 loops, best of 3: 330 µs per loop
So having the index is only advantageous when you have many lookups of this type to perform.
Sometimes the index plays a role in reshaping the DataFrame. Many functions, such as set_index, stack, unstack, pivot, pivot_table, melt,
lreshape, and crosstab, all use or manipulate the index.
Sometimes we want the DataFrame in a different shape for presentation purposes, or for join, merge or groupby operations. (As you note joining can also be done based on column values, but joining based on the index is faster.) Behind the scenes, join, merge and groupby take advantage of fast index lookups when possible.
Time series have resample, asfreq and interpolate methods whose underlying implementations take advantage of fast index lookups too.
So in the end, I think the origin of the index's usefulness, why it shows up in so many functions, is due to its ability to perform fast hash lookups.
Answer from unutbu on Stack Overflowpython - What is the point of indexing in pandas? - Stack Overflow
dumb, obvious thing I must be missing - what is an 'index' in pandas and how can I use it?
Do you use pandas Index?
python - Correct way to check if Pandas DataFrame index is a certain type (DatetimeIndex) - Stack Overflow
Like a dict, a DataFrame's index is backed by a hash table. Looking up rows based on index values is like looking up dict values based on a key.
In contrast, the values in a column are like values in a list.
Looking up rows based on index values is faster than looking up rows based on column values.
For example, consider
df = pd.DataFrame({'foo':np.random.random(), 'index':range(10000)})
df_with_index = df.set_index(['index'])
Here is how you could look up any row where the df['index'] column equals 999.
Pandas has to loop through every value in the column to find the ones equal to 999.
df[df['index'] == 999]
# foo index
# 999 0.375489 999
Here is how you could lookup any row where the index equals 999. With an index, Pandas uses the hash value to find the rows:
df_with_index.loc[999]
# foo 0.375489
# index 999.000000
# Name: 999, dtype: float64
Looking up rows by index is much faster than looking up rows by column value:
In [254]: %timeit df[df['index'] == 999]
1000 loops, best of 3: 368 µs per loop
In [255]: %timeit df_with_index.loc[999]
10000 loops, best of 3: 57.7 µs per loop
Note however, it takes time to build the index:
In [220]: %timeit df.set_index(['index'])
1000 loops, best of 3: 330 µs per loop
So having the index is only advantageous when you have many lookups of this type to perform.
Sometimes the index plays a role in reshaping the DataFrame. Many functions, such as set_index, stack, unstack, pivot, pivot_table, melt,
lreshape, and crosstab, all use or manipulate the index.
Sometimes we want the DataFrame in a different shape for presentation purposes, or for join, merge or groupby operations. (As you note joining can also be done based on column values, but joining based on the index is faster.) Behind the scenes, join, merge and groupby take advantage of fast index lookups when possible.
Time series have resample, asfreq and interpolate methods whose underlying implementations take advantage of fast index lookups too.
So in the end, I think the origin of the index's usefulness, why it shows up in so many functions, is due to its ability to perform fast hash lookups.
In my experience, indexing only serves to make the library more complicated for data science tasks. (As WestCoastProjects says, "an amazing PITA")
Indexes are supposed to be more performant, somewhat like a SQL db index, however this deviates from the tried-and-trusted relational model by having a special case that is more of an implementation detail. Dplyr makes a point to not use row labels because it adds unnecessary complexity as a special-case. Polars does also:
Polars aims to have predictable results and readable queries, as such we think an index does not help us reach that objective. We believe the semantics of a query should not change by the state of an index or a
reset_indexcall.
...As such, it is our conviction that not having indices make things simpler, more explicit, more readable and less error-prone.
Note that an 'index' data structure as known in databases will be used by Polars as an optimization technique.
In pandas this becomes confusing functions like:
| With Label/Index | With Column (SQL-style) |
|---|---|
.loc |
[] subsetting |
DataFrame.join() |
pandas.merge() (SQL-style join) |
DataFrame.filter() |
Row subsetting |
DataFrame.groupby(by=label), makes the grouping variable the index |
DataFrame.groupby(by="col", as_index=False) |
| Hierarchical Multi-Index | Just use columns! |
So far, I've never had any practical performance issues ignoring the index. In-memory, DuckDB and Polars beat Pandas by a lot in performance benchmarks. Pandas, like dplyr, can't handle large datasets that don't fit into memory anyway, and Spark or an SQL database scales much better. Polars can maybe handle it although it looks still experimental.
I'm coming from an R background. I'm trying to get into Python since for me R comes very naturally - and I'd like to expand my skills.
I'm really trying to get into Python/Pandas/Sklearn but I see so much about the 'index' and axises in Pandas. I've come to gather that "index" means the 'row number'?? But thats about it. I can't wrap my head around how to use index so make my code better or understand them or why in the world I would ever need them?
Sorry, can someone explain this to me and maybe some examples? I see this word mentioned extremely frequently but again can't understand how this is important...
Hi all,
I am curious about whether people make use of pandas Index (and MultiIndex). To me it feels easier to think about my dataframes without any Index, but then I use reset_index etc. quite often, because pandas kind of forces an Index in many operations. Furthermore, having one column as an Index means using different methods and way of thinking to manipulate the dataframe, which feels inconsistent and error-prone.
For those who are using the Index, do you see it as a great advantage? I can imagine some operations will be a bit faster, but what about if that is not a concern?
Thanks!
As of 2021, here is the up to date way of checking this:
>>> df.index.inferred_type == "datetime64"
>>> True
So you could add something like this into your application:
assert df.index.inferred_type == 'datetime64', "must have a datetime index"
Cheers
The more robust way is to use pandas.api.types, e.g. ptypes.is_datetime64_any_dtype.
For example,
import pandas.api.types as ptypes
ptypes.is_datetime64_dtype(df.index)
ptypes.is_numeric_dtype(df.index)
ptypes.is_string_dtype(df.index)
It's related to this answer for column types: Asserting column(s) data type in Pandas