py-datatable 'in' 运算符?



我无法使用预定义的项目列表执行标准的in操作。我想做这样的事情:

# Construct a simple example frame
from datatable import *
df = Frame(V1=['A','B','C','D'], V2=[1,2,3,4])
# Filter frame to a list of items (THIS DOES NOT WORK)
items = ['A','B']
df[f.V1 in items,:]

此示例导致错误:

TypeError: A boolean value cannot be used as a row selector

不幸的是,似乎没有用于in操作的内置对象。我想使用类似 R 语言原生的%in%运算符。有什么方法可以在 python 中完成此操作吗?

我可以使用多个"等于"运算符来采用这种方法,但是当您要考虑大量项目时,这很不方便:

df[(f.V1 == 'A') | (f.V1 == 'B'),:]

数据表 0.10.1
Python 3.6

你也可以试试这个:

首先将所有必要的包导入为,

import datatable as dt
from datatable import by,f,count
import functools
import operator

创建示例数据表:

DT = dt.Frame(V1=['A','B','C','D','E','B','A'], V2=[1,2,3,4,5,6,7])

列出要在观测值中过滤的值,在您的情况下是

sel_obs = ['A','B']

现在使用funtools和运算符模块创建一个过滤器表达式,

filter_rows = functools.reduce(operator.or_,(f.V1==obs for obs in sel_obs))

最后在数据表上应用上面创建的过滤器

DT[fil_rows,:]

其输出为-

Out[6]: 
| V1  V2
-- + --  --
0 | A    1
1 | B    2
2 | B    6
3 | A    7
[4 rows x 2 columns]

您可以使用运算符来执行不同类型的过滤。

@sammyweemy的解决方案也应该有效。

事实证明,当你将表达式列表传递给pythondatatable时,它会将它们评估为or

所以你可以做:

import datatable
df = datatable.Frame(V1=['A','B','C','D'], V2=[1,2,3,4])
items = ['A','B']
df[[datatable.f.V1 == i for i in items],:]

请注意,对此有一些注意事项:文档中没有描述它,我绝对不知道它是否总是有效。此外,它也只能过滤一列 - 如果您尝试过滤行,V1==A or V2==1list 方法会创建重复项。

如果您需要执行一些更精细的过滤,只需调整列表中的过滤表达式,例如:

df[([(datatable.f.V1 == i) & (datatable.f.V2 >= 2) for i in items]),:]

正如预期的那样,这将仅返回示例中的第二行。

我在pydatatable中没有找到in函数;但是,您的用例有一个技巧:

items = ['A','B']
regex = f"{'|'.join(items)}"
df[f.V1.re_match(regex),:]

V1   V2
▪▪▪▪  ▪▪▪▪
0   A   1
1   B   2
2 rows × 2 columns

这是对另一个问题的答案:链接。我在文档中也找不到此功能。希望随着时间的推移,文档会得到改进,并且还会包含更多功能。

在我的情况下,项目列表非常大,因此接受的答案会导致 python 内核死亡。我的解决方法是创建临时框架,将列表作为键,并创建具有所有行的任何值的列,然后将我的框架与临时框架左连接过滤所有不是 NA 的行:

DT1 = dt.Frame(A = ['a', 'b', 'c', 'd'])
TEMP_DT = dt.Frame(A=['a', 'b'], FOO=[1, 1])
TEMP_DT.key = 'A'
DT1[:, :, join(TEMP_DT)][~dt.isna(f.FOO),:]

最新更新