根据是否在列表中过滤 python 数据表的行
Filter rows of python datatable based on whether it is in a list
我刚开始使用 python 数据表,这是我正在关注的 tutorial
如何过滤掉列表中包含特定列中的值的行?
基本上这是我正在使用的代码:
import datatable as dt
sfr = dt.fread(os.path.join(dirName, 'Results.csv'))
sfr
Out[25]:
| ioid itemtype date itemid tid value
-------- + ---------- -------- -------- ------- ------------ -------
0 | 1 1 7-1-2022 9015 531 0.0283
1 | 1 1 7-1-2022 9015 532 0.0071
2 | 1 1 7-1-2022 9016 534 0.0065
3 | 1 1 7-1-2022 9017 1018 0.0005
我正在尝试执行以下操作
ids = [9016, 9017]
sft[dt.f.itemid.isin(ids)]
但是,我无法使语法正常工作。
期望的输出是:
| ioid itemtype date itemid tid value
-------- + ---------- -------- -------- ------- ------------ -------
2 | 1 1 7-1-2022 9016 534 0.0065
3 | 1 1 7-1-2022 9017 1018 0.0005
因为 Pydatatable 不明确支持过滤值列表(参见 feature request),以下解决方案可能看起来不太直观。尽管如此,它仍然通过使用数据表连接函数来完成此类过滤所要做的事情:
ids = [9016, 9017]
f = dt.Frame(itemid = ids)
sfr.key = "itemid"
sfr_filtered = f[:, :, dt.join(sfr)]
这些步骤包括:
- 创建一个框架(数据表),其中包含与要过滤的列同名的单个列,并在该框架内存储值列表
- 在被过滤的列上键入原始帧
- 连接帧以使用数据表连接执行过滤
这里有一个问题:当前连接有限制 - 它只有左外连接和连接列(上面解决方案中 sfr
中的 itemid
)必须具有唯一值,否则 sfr.key = "itemid"
抛出此错误:
ValueError: Cannot set a key: the values are not unique
由于这些强大的假设,当 itemid
不包含唯一值时,它将不起作用。在那种情况下,我们转向连接并在添加到包含列表的框架的虚拟列上添加额外的过滤器:
ids = [9016, 9017]
f = dt.Frame(itemid = ids, dummy = [0, 0])
f.key = "itemid"
sfr_filtered = sfr[:, :, dt.join(f)][~dt.isna(dt.f.dummy), :]
此解决方案将始终有效,但显然效率较低,因为总是连接所有行并进行额外过滤以删除不匹配的行。有关 Pydatatable 连接当前状态的更多详细信息,您可以找到文档 here.
更新
为了完整起见,我添加了另一个(可以说是更直接的)解决方案,该解决方案是 Pasha(Pydatatable 的创建者和维护者)从 借来的:
import functools
import operator
filter = functools.reduce(operator.or_, (dt.f.itemid == id for id in ids))
sfr[filter, :]
在此功能请求 https://github.com/h2oai/datatable/issues/699 实现之前,上面显示的解决方案之一会根据值列表进行过滤。
我刚开始使用 python 数据表,这是我正在关注的 tutorial
如何过滤掉列表中包含特定列中的值的行?
基本上这是我正在使用的代码:
import datatable as dt
sfr = dt.fread(os.path.join(dirName, 'Results.csv'))
sfr
Out[25]:
| ioid itemtype date itemid tid value
-------- + ---------- -------- -------- ------- ------------ -------
0 | 1 1 7-1-2022 9015 531 0.0283
1 | 1 1 7-1-2022 9015 532 0.0071
2 | 1 1 7-1-2022 9016 534 0.0065
3 | 1 1 7-1-2022 9017 1018 0.0005
我正在尝试执行以下操作
ids = [9016, 9017]
sft[dt.f.itemid.isin(ids)]
但是,我无法使语法正常工作。
期望的输出是:
| ioid itemtype date itemid tid value
-------- + ---------- -------- -------- ------- ------------ -------
2 | 1 1 7-1-2022 9016 534 0.0065
3 | 1 1 7-1-2022 9017 1018 0.0005
因为 Pydatatable 不明确支持过滤值列表(参见 feature request),以下解决方案可能看起来不太直观。尽管如此,它仍然通过使用数据表连接函数来完成此类过滤所要做的事情:
ids = [9016, 9017]
f = dt.Frame(itemid = ids)
sfr.key = "itemid"
sfr_filtered = f[:, :, dt.join(sfr)]
这些步骤包括:
- 创建一个框架(数据表),其中包含与要过滤的列同名的单个列,并在该框架内存储值列表
- 在被过滤的列上键入原始帧
- 连接帧以使用数据表连接执行过滤
这里有一个问题:当前连接有限制 - 它只有左外连接和连接列(上面解决方案中 sfr
中的 itemid
)必须具有唯一值,否则 sfr.key = "itemid"
抛出此错误:
ValueError: Cannot set a key: the values are not unique
由于这些强大的假设,当 itemid
不包含唯一值时,它将不起作用。在那种情况下,我们转向连接并在添加到包含列表的框架的虚拟列上添加额外的过滤器:
ids = [9016, 9017]
f = dt.Frame(itemid = ids, dummy = [0, 0])
f.key = "itemid"
sfr_filtered = sfr[:, :, dt.join(f)][~dt.isna(dt.f.dummy), :]
此解决方案将始终有效,但显然效率较低,因为总是连接所有行并进行额外过滤以删除不匹配的行。有关 Pydatatable 连接当前状态的更多详细信息,您可以找到文档 here.
更新
为了完整起见,我添加了另一个(可以说是更直接的)解决方案,该解决方案是 Pasha(Pydatatable 的创建者和维护者)从
import functools
import operator
filter = functools.reduce(operator.or_, (dt.f.itemid == id for id in ids))
sfr[filter, :]
在此功能请求 https://github.com/h2oai/datatable/issues/699 实现之前,上面显示的解决方案之一会根据值列表进行过滤。