【问题标题】:Run logical Expressions against pandas dataframe针对 pandas 数据框运行逻辑表达式
【发布时间】:2015-09-18 07:42:46
【问题描述】:

我正在尝试通过将条件应用于列(以逻辑表达式的形式)从 pandas 数据框中选择行。

示例数据框如下所示:

    id             userid                code
    0            645382311          12324234234
    1            645382311          -2434234242
    2            645382312          32536365654
    3            645382312          12324234234

...

例如,我希望通过对列“代码”应用逻辑表达式来获得下一个结果:

    case 1: (12324234234 OR -2434234242) AND NOT 32536365654
    case 2: (12324234234 AND -2434234242) OR NOT 32536365654
    must give a result for both cases:
    userid: 645382311

上面的逻辑说: 对于案例 1 - 只给我那些具有至少一个值(12324234234 或 -2434234242)并且在整个数据框中没有 32536365654 的用户 ID。 对于案例 2 - 我只需要那些在数据框中同时具有两个代码(12324234234 和 -2434234242)或任何代码但不是 32536365654 的用户 ID。

如下语句返回空DataFrame:

    flt = df[(df.code == 12324234234) & (df.code == -2434234242)]
    print("flt: ", flt)

结果(这很有意义):

    flt:  Empty DataFrame

对于处理此类情况的任何提示,我们将不胜感激。

【问题讨论】:

  • 条件似乎有点奇怪:对于案例 1,AND NOT 32536365654 是多余的;对于案例 2,(12324234234 AND -2434234242) 是多余的。
  • 在条件下一切正常。对于案例 1,我只需要具有至少一个值(12324234234 或 -2434234242)并且在整个数据框中没有 32536365654 的用户 ID。对于案例 2,一切正常,我只需要那些在数据框中同时具有代码或任何代码但没有 32536365654 的用户 ID。
  • 您可以找到代码为 32536365654 的用户,然后使用 df[~df.userid.isin( )] 方法选择没有该代码的用户。见stackoverflow.com/questions/19960077/…

标签: python pandas dataframe logical-operators


【解决方案1】:

作为一种简单的方法,我会将您的示例表转换为布尔存在矩阵,然后您可以执行所需的逻辑:

import pandas
sample = pandas.DataFrame([[645382311, 12324234234], [645382311, -2434234242], [645382312, 32536365654], [645382312, 12324234234]], columns=['userid', 'code'])
# Add a column of True values
sample['value'] = True
# Pivot to boolean presence matrix and remove MultiIndex
presence = sample.pivot(index='userid', columns='code').fillna(False)['value']
# Perform desired boolean tests
case1 = (presence[12324234234] | presence[-2434234242]) & ~(presence[32536365654])
case2 = (presence[12324234234] & presence[-2434234242]) | ~(presence[32536365654])

case 变量将包含每个用户 ID 的布尔测试结果。

【讨论】:

  • 谢谢你,@pbarber!它运作良好。唯一的问题是在 (-1111111AND2222222)NOT(-3333333) 这样的形式中定义案例我正在使用 regexp 将它们转换为适当的形式 case = '((presence[-1111111] & presence[2222222]) &~ (presence[-3333333]))' 以便执行布尔测试。由于这种情况的类型为 String,因此评估它的唯一方法是使用 eval(case)。您有任何想法或其他可用的选项来评估此类案例吗?
猜你喜欢
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多