动态构建索引以对 pandas 中的记录进行分类

Posted

技术标签:

【中文标题】动态构建索引以对 pandas 中的记录进行分类【英文标题】:Dynamically building indexes to classify records in pandas 【发布时间】:2019-03-12 21:02:55 【问题描述】:

我正在尝试编写一个简单的记录分类器。我想添加一个其值对记录进行分类的列。我想将我的分类规则编入 yaml 或类似文件以进行维护。

我正在使用 Pandas,因为这似乎是使用 python 中的 csv 记录执行此操作的最佳方法。我愿意接受其他建议。我是 pandas 的新手,我的 python 技能被礼貌地描述为“为什么这看起来像 perl?”

我得到了一个数据框(trans),我想应用我的规则如下:

trans['class'][(trans['foo'] > 5) & (trans['bar'].str.contains(re.compile('baz|one|two', re.I))] = 'Record Type 1'

这是交互式的。我希望能够从我的 yaml 文件中的每个规则动态生成分类索引"(trans['foo'] > 5) & (trans['bar'].str.contains(re.compile('baz|one|two', re.I))"。我已经成功构建了字符串,这样我就有了这样的东西:

slice = "(trans['foo'] > 5) & (trans['bar'].str.contains(re.compile('baz|one|two', re.I))" trans['class'][slice] = 'Record Type 1'

这不起作用。我应该怎么做?

【问题讨论】:

【参考方案1】:

我认为您不应该将条件放在引号内。所以应该是

slice = (trans[`foo`] > 5) & (trans['bar'].str.contains(re.compile('baz|one|two', re.I)))
trans['class'][slice] = "Record Type 1"

【讨论】:

如果表达式以字符串s 的形式出现,您可以使用slice = eval(s)。 @jpp 的笔记都很棒,值得考虑,尤其是第二名。 我在代码中构建了自己的字符串,缺少的是 eval。我误解了切片在链式逻辑中的含义。我在文档中简要阅读了链式对话,并决定它不适用于我的情况,因为我不担心覆盖数据框。也就是说,既然我知道如何避免它,我打算避免它。【参考方案2】:

需要注意的几点:

    引号表示 Python 中的字符串。不要使用它们来包围布尔掩码的计算。 不要使用链式索引。它是文档中的explicitly discouraged,它可能会导致意外的副作用,或者是在修改视图还是副本时产生歧义。您可以改用pd.DataFrame.locpd.Series.str.contains 已经支持正则表达式并且默认为regex=True,您不需要使用re 模块。

为了便于阅读,您可以拆分和组合掩码。这是一个例子:

m1 = trans['foo'] > 5
m2 = trans['bar'].str.contains('baz|one|two', case=False)

trans.loc[m1 & m2, 'class'] = 'Record Type 1'

通常昂贵的部分,m2 的计算,可以通过专业算法进行优化,详情请参阅this answer。

【讨论】:

您将如何处理在运行时之前存在未知数量的条件的情况?即可能需要 m1、m1&m2 或 m1&m2&m3 等。你能像 m = m & new_condition 这样迭代吗? 当然,您可以通过这种方式链接任意数量的布尔系列,例如m = m1 & m2 & (m3 | m4) & (m5 | m6),然后计算m = m & m7等。 谢谢您-我点击了并忘记了检查-doh!这看起来非常有帮助。谢谢。

以上是关于动态构建索引以对 pandas 中的记录进行分类的主要内容,如果未能解决你的问题,请参考以下文章

创建特征向量以对空中图像中的片段进行分类

将连续月份分组在一起以对 HIVE 中的数据进行分类

将日期转换为浮点数以对 Pandas 数据框进行线性回归

动态构建大型数据框(spark 或 pandas)以导出到 csv 的方法

如何使用单个索引更新多索引数据框中的记录

使用 n-d numpy 数组作为索引对 Panda 的数据帧进行分层索引