对数据帧或数据系列应用多个筛选器的有效方法

我有一个场景,用户希望对一个数据帧或序列对象应用几个过滤器。本质上,我想有效地将用户在运行时指定的一系列过滤(比较操作)链接在一起

过滤器应为添加剂(即,应用的每个过滤器应缩小结果范围)

我目前正在使用reindex(),但每次都会创建一个新对象并复制底层数据(如果我正确理解文档的话)。因此,在过滤大型系列或数据帧时,这可能会非常低效

我认为使用apply()map()或类似的方法可能会更好。我对熊猫还不太熟悉,所以我还是试着去了解一切

TL;博士

我希望采用以下形式的字典,将每个操作应用于给定的Series对象,并返回一个“筛选”的Series对象

relops={'>=':[1],'<=':[1]}

长例子

我将从一个我目前拥有的示例开始,只过滤一个序列对象。以下是我当前使用的函数:

def应用再操作(系列,再操作):
"""
传递关系运算符字典以在给定的系列对象上执行
"""
对于op,relops.iteritems()中的VAL:
op_func=ops[op]
对于val中的val:
过滤=运算函数(系列,val)
series=series.reindex(series[过滤])
返回序列

用户提供一个字典,其中包含要执行的操作:

&gt&燃气轮机&燃气轮机;数据帧({'col1':[0,1,2],'col2':[10,11,12]})
&燃气轮机&燃气轮机&燃气轮机;打印df
&燃气轮机&燃气轮机&燃气轮机;打印df
col1 col2
0     0    10
1     1    11
2     2    12
&燃气轮机&燃气轮机&燃气轮机;从ge的运营商进口
&燃气轮机&燃气轮机&燃气轮机;ops={'>=':ge'<=':le}
&燃气轮机&燃气轮机&燃气轮机;应用重新操作(df['col1'],{'>=':[1]})
可乐
1       1
2       2
姓名:col1
&燃气轮机&燃气轮机&燃气轮机;应用_relops(df['col1',relops={'>=':[1],'<=':[1]})
可乐
1       1
姓名:col1

同样,我上述方法的“问题”是,我认为中间步骤可能存在大量不必要的数据复制

此外,我还想对此进行扩展,以便传入的字典可以包括要运算符打开的列,并基于输入字典过滤整个数据帧。然而,我假设任何适用于该系列的东西都可以轻松地扩展为数据帧

熊猫(和numpy)允许布尔索引,这将更加有效:

[11]on

:df.loc[df['col1']>=1'col1']
Output[11]:
1    1
2    2
姓名:col1
At[12]on:df[df['col1']>=1]
Output[12]:
col1 col2
1     1    11
2     2    12
At[13]on:df[(df['col1']>=1)&(df['col1']<=1)]
Output[13]:
col1 col2
1     1    11

如果您想为此编写帮助函数,请考虑以下几行:


[14]on

:定义b(x,col,op,n):
返回op(x[col],n)
At[15]on:定义f(x,*b):
返回x[(np.logical_和(*b))]
In[16]:b1=b(df,'col1',ge,1)
In[17]:b2=b(df,'col1',le,1)
In[18]:f(df,b1,b2)
Output[18]:
col1 col2
1     1    11

更新:pandas 0.13为此类用例提供了一种查询方法,假设列名是有效的标识符,下面的工作(并且对于大帧来说可能更有效,因为它在幕后使用numexpr):

[21]on

:df.query('col1<=1<=col1')
Output[21]:
col1 col2
1     1    11

发表评论