我正在尝试编写一个简单的记录分类器。我想添加一个其值对记录进行分类的列。我想在 yaml 或类似文件中编纂我的分类规则以进行维护。
我正在使用 Pandas,因为这似乎是在 python 中使用 csv 记录执行此操作的最佳方式。我愿意接受其他建议。我是熊猫的新手,我的蟒蛇技能被礼貌地描述为"为什么这看起来像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'
这行不通。我应该怎么做?
需要注意的几点:
- 引号表示 Python 中的字符串。不要使用它们来包围布尔掩码的计算。
- 不要使用链式索引。文档中明确不鼓励这样做,这可能会导致意想不到的副作用,或者您是修改视图还是副本的歧义。您可以改用
pd.DataFrame.loc
。 pd.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
计算 ,可以通过诉诸专业算法进行优化,有关详细信息,请参阅此答案。
我认为你不应该把条件放在引号里。所以应该是
slice = (trans[`foo`] > 5) & (trans['bar'].str.contains(re.compile('baz|one|two', re.I)))
trans['class'][slice] = "Record Type 1"