Python pandas 按多个索引范围切片数据帧

Posted

技术标签:

【中文标题】Python pandas 按多个索引范围切片数据帧【英文标题】:Python pandas slice dataframe by multiple index ranges 【发布时间】:2017-01-16 13:24:33 【问题描述】:

按更多索引范围(例如,10:1225:28)对数据帧进行切片的 Python 方法是什么?

我想要一个更优雅的方式:

df = pd.DataFrame('a':range(10,100))
df.iloc[[i for i in range(10,12)] + [i for i in range(25,28)]]

结果:

     a
10  20
11  21
25  35
26  36
27  37

这样的东西会更优雅:

df.iloc[(10:12, 25:28)]

【问题讨论】:

【参考方案1】:

在@KevinOelen 使用 Panda 的 isin 函数的基础上,这是一种 Python 方式(Python 3.8),可以查看 Pandas DataFrame 或 GeoPandas GeoDataFrame,只显示几行头部和尾部。此方法不需要导入numpy。

要使用只需调用glance(your_df)。文档字符串中的附加说明。

import pandas as pd
import geopandas as gpd  # if not needed, remove gpd.GeoDataFrame from the type hinting and no need to import Union
from typing import Union


def glance(df: Union[pd.DataFrame, gpd.GeoDataFrame], size: int = 2) -> None:
    """ Provides a shortened head and tail summary of a Dataframe or GeoDataFrame in Jupyter Notebook or Lab.

    Usage
    ----------
    # default glance (2 head rows, 2 tail rows)
    glance( df )
    
    # glance defined number of rows in head and tail (3 head rows, 3 tails rows)
    glance( df, size=3 )

    Parameters
    ----------
    :param df: Union[pd.DataFrame, gpd.GeoDataFrame]: A (Geo)Pandas data frame to glance at.
    :param size: int: The number of rows in the head and tail to display, total rows will be double provided size.
    :return: None: Displays result in Notebook or Lab.
    """
    
    # min and max of the provided dataframe index
    min_ = df.index.min()
    max_ = df.index.max()

    # define slice
    sample = [i for i in range(min_, size)] + [i for i in range(max_ - size, max_)]

    # slice
    df = df[df.index.isin(sample)]
    
    # display
    display( df )

【讨论】:

【参考方案2】:

你可以使用numpy的r_“切片技巧”:

df = pd.DataFrame('a':range(10,100))
df.iloc[pd.np.r_[10:12, 25:28]]

注意:这会给出警告The pandas.np module is deprecated and will be removed from pandas in a future version. Import numpy directly instead。为此,您可以import numpy as np 然后按以下方式切片:

df.iloc[np.r_[10:12, 25:28]]

这给出了:

     a
10  20
11  21
25  35
26  36
27  37

【讨论】:

没有比这更简洁的了。 np.r_ 正是为此目的而构建的。而且,我学到了一些东西。希望我能 +2。 需要注意的一点:要获得负索引(即相当于df.iloc[-2:]),您必须包含一个零:df.iloc[pd.np.r_[:2, -2:0]] pd.np.r_ 已弃用,因此我已更新答案以直接使用 numpy【参考方案3】:

您可以利用 pandas isin 功能。

df = pd.DataFrame('a':range(10,100))
ls = [i for i in range(10,12)] + [i for i in range(25,28)]
df[df.index.isin(ls)]


    a
10  20
11  21
25  35
26  36
27  37

【讨论】:

为此而来...谢谢!提供了一个包含您的答案。

以上是关于Python pandas 按多个索引范围切片数据帧的主要内容,如果未能解决你的问题,请参考以下文章

具有多个列范围的 Pandas 数据框切片[重复]

pandas常用

Python中偶尔遇到的细节疑问:去除列名特殊字符标准差出现nan切片索引可超出范围range步长

Pandas - 索引操作

python--pandas切片

Python数据分析pandas日期范围date_range