Python 使用多个间隔选择熊猫中的行(pd.Interval范围对象)

Python 使用多个间隔选择熊猫中的行(pd.Interval范围对象),python,pandas,etl,Python,Pandas,Etl,我需要使用pd.Interval跨多个bin范围选择记录 df = pd.DataFrame({'my_col': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}) df['my_col_bin'] = pd.cut(x=df['my_col'], bins=[0, 3, 6, 9, 12], right=False, include_lowest=True) 例如,我希望选择属于范围[3,12]的所有记录。我希望使用单个pd.Interval range获得以下输出

我需要使用pd.Interval跨多个bin范围选择记录

df = pd.DataFrame({'my_col': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]})
df['my_col_bin'] = pd.cut(x=df['my_col'], bins=[0, 3, 6, 9, 12], right=False, include_lowest=True)
例如,我希望选择属于范围[3,12]的所有记录。我希望使用单个pd.Interval range获得以下输出,而不单独指定每个间隔的条件:

2   3   [3, 6)
3   4   [3, 6)
4   5   [3, 6)
5   6   [6, 9)
6   7   [6, 9)
7   8   [6, 9)
8   9   [9, 12)
9   10  [9, 12)
10  11  [9, 12)
我尝试了以下方法,但没有成功

df[df['my_col_bin'] == pd.Interval(3, 12, closed='left')]
以下选择适用于单个间隔,但pd.interval似乎不支持多个范围

df[df['my_col_bin'] == pd.Interval(3, 6, closed='left')]
是否有可能在不明确指定每个间隔条件的情况下跨存储箱选择范围?是否有一种简洁的方法来执行选择而不单独过滤每个间隔

它确实需要一个
应用程序
,但事实证明,即使对于一个大数据帧,它也相当快。(在我的机器上,100万行大约需要50毫秒)

它确实需要一个
应用程序
,但事实证明,即使对于一个大数据帧,它也相当快。(在我的机器上,100万行大约需要50毫秒)


选择这种方式怎么样

df[(df['my_col'] >= 3) & (df['my_col'] < 12)]
df[(df['my_col']>=3)和(df['my_col']<12)]

选择这种方式怎么样

df[(df['my_col'] >= 3) & (df['my_col'] < 12)]
df[(df['my_col']>=3)和(df['my_col']<12)]
您问:

是否有可能在不明确指定每个间隔条件的情况下跨存储箱选择范围?是否有一种简洁的方法来执行选择而不单独过滤每个间隔

一般来说,答案是:

“一般”表示列中的各个间隔(在您的示例中它们是)之间没有关系,也没有“目标”间隔(
[3,12)
)与列中间隔(在您的示例中也是)之间的关系

(请参阅我对您的问题的回答,该问题在您的示例中利用了这种关系。)


为什么?

区间不是一个数学区间(从实数的连续集合的意义上讲)

Pandas interval只是其属性的有序四元组
(.left、.right、.closed\u left、.closed\u right)

例如,您的间隔
[3,12)
不过是四个
(3,12,True,False)


这会带来什么后果?

这意味着不存在并集、交集、差集或子集等集合操作/关系,而最后一个正是您需要的


我怎么能看出间隔只不过是提到的四个小间隔?

从类
Interval
提供的方法和属性中,或间接地从类
Interval
提供的方法和属性中。所有这些方法和属性都以非常简单的方式从上述四元组中派生:

你问:

是否有可能在不明确指定每个间隔条件的情况下跨存储箱选择范围?是否有一种简洁的方法来执行选择而不单独过滤每个间隔

一般来说,答案是:

“一般”表示列中的各个间隔(在您的示例中它们是)之间没有关系,也没有“目标”间隔(
[3,12)
)与列中间隔(在您的示例中也是)之间的关系

(请参阅我对您的问题的回答,该问题在您的示例中利用了这种关系。)


为什么?

区间不是一个数学区间(从实数的连续集合的意义上讲)

Pandas interval只是其属性的有序四元组
(.left、.right、.closed\u left、.closed\u right)

例如,您的间隔
[3,12)
不过是四个
(3,12,True,False)


这会带来什么后果?

这意味着不存在并集、交集、差集或子集等集合操作/关系,而最后一个正是您需要的


我怎么能看出间隔只不过是提到的四个小间隔?

从类
Interval
提供的方法和属性中,或间接地从类
Interval
提供的方法和属性中。所有这些方法和属性都以非常简单的方式从上述四元组中派生:


我利用了你的专栏
my\u col\u bin
中的间隔与你的目标间隔
[3,12)
之间的紧密关系,这只不过是该专栏的3个间隔

(请参阅我对你的问题的回答,这是关于一般情况的。)


我利用了你的专栏
my\u col\u bin
中的间隔与你的目标间隔
[3,12)
之间的紧密关系,这只不过是该专栏的3个间隔

(请参阅我对你的问题的回答,这是关于一般情况的。)


我如何使用filter而不是apply来使用它?@verkter过滤是什么意思?我使用它来创建一个掩码,然后过滤到您想要的行。您可以在一行
df[df['my_col_bin'].apply(lambda x:…)]
但我将其拆分以使其更清晰。是否有更清晰的选择方法,或者应用是必要的?@verkter,没有间隔,您通常需要使用应用。我的意思是,您可以将边界表示为numpy数组,但在这一点上,您可能需要付出代价才能获得边界。我经常对其性能感到惊讶使用间隔应用的e。使用间隔对象应用的
apply
速度很快。即使有1亿行,应用也只需要1s左右,所以并不可怕。出于好奇,在您看来,这段代码有什么地方不干净?@verkter如何使用过滤器而不是应用?@verkter过滤是什么意思?我用它来解决问题创建一个掩码,然后过滤到您想要的行。您可以在一行
df[df['my\u col\u bin']中完成。应用(lambda x:…)]
但我将其拆分以使其更清晰。我
df[(df['my_col'] >= 3) & (df['my_col'] < 12)]
closed_left
closed_right
is_empty
left
length
mid
open_left
open_right
overlaps()
right
In[1]: intervals = {interval for interval in df.my_col_bin 
                       if interval.left >= 3 and interval.right <= 12}
In[2]: intervals
{Interval(3, 6, closed='left'),
 Interval(6, 9, closed='left'),
 Interval(9, 12, closed='left')}
In[1]: intervals = [pd.Interval(i, i + 3, closed="left") for i in range(3, 10, 3)]
In[2]: intervals
[Interval(3, 6, closed='left'),
 Interval(6, 9, closed='left'),
 Interval(9, 12, closed='left')]
In[3]: df[df.my_col_bin.isin(intervals)]
    my_col my_col_bin
2        3     [3, 6)
3        4     [3, 6)
4        5     [3, 6)
5        6     [6, 9)
6        7     [6, 9)
7        8     [6, 9)
8        9    [9, 12)
9       10    [9, 12)
10      11    [9, 12)