【问题标题】:Using vectorized logical not in pandas to filter a frame在 pandas 中使用矢量化逻辑 not 过滤帧
【发布时间】:2019-01-30 19:47:18
【问题描述】:

我有一个要修剪的 pandas 数据框。我想取出部分为 2 且标识符不以数字开头的行。首先,我想数一数。如果我运行这个

len(analytic_events[analytic_events['section']==2].index)

我得到结果 1247669

当我缩小范围并运行它时

len(analytic_events[(analytic_events['section']==2) & ~(analytic_events['identifier'][0].isdigit())].index)

我得到完全相同的答案:1247669

例如,我知道其中有 10 行以 this 作为其标识符

.help.your_tools.subtopic2

不以数字开头,并且 15,000 行以此为标识符

240.1007

确实以数字开头。

为什么我的过滤器会通过所有行,而不仅仅是那些标识符不以数字开头的行?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用str 处理文本函数,使用str[0] 处理字符串的第一个值,最后一个sum 处理计数Trues 值:

    mask= ((analytic_events['section']==2) & 
           ~(analytic_events['identifier'].str[0].str.isdigit()))
    
    print (mask.sum())
    

    如果性能很重要并且没有缺失值,则使用列表推导:

    arr = ~np.array([x[0].isdigit() for x in analytic_events['identifier']])
    mask = ((analytic_events['section']==2) & arr)
    

    编辑:

    为什么我的过滤器会通过所有行,而不仅仅是那些标识符不以数字开头的行?

    如果你的解决方案的测试输出:

    analytic_events = pd.DataFrame(
                            {'section':[2,2,2,3,2],
                             'identifier':['4hj','8hj','gh','th','h6h']})
    
    print (analytic_events)
       section identifier
    0        2        4hj
    1        2        8hj
    2        2         gh
    3        3         th
    4        2        h6h
    

    获取列的第一个值:

    print ((analytic_events['identifier'][0]))
    4hj
    

    检查标量的位数:

    print ((analytic_events['identifier'][0].isdigit()))
    False
    
    print (~(analytic_events['identifier'][0].isdigit()))
    -1
    

    使用带有第一个掩码的链将其转换为True

    print ((analytic_events['section']==2) & ~(analytic_events['identifier'][0].isdigit()))
    0     True
    1     True
    2     True
    3    False
    4     True
    Name: section, dtype: bool
    

    所以它的工作原理与不存在第二个掩码一样:

    print (analytic_events['section']==2)
    0     True
    1     True
    2     True
    3    False
    4     True
    Name: section, dtype: bool
    

    【讨论】:

    • 谢谢,对我天真的“解决方案”所做的分析特别有帮助
    • 为什么 isdigit() 应用到 False 时在我的解决方案的测试输出的最后一行给出 -1 而不会引发错误?
    • @dumbledad - 如果检查 print (~False) 它返回 -1,但如果将 ti 转换为 bool 则得到 True - print (bool(~False))
    • 我从你的第一个解决方案中得到一个类型错误,当我运行它时我得到TypeError: bad operand type for unary ~: 'float'
    • @dumbledad - 解决方案是将缺失值转换为False,例如mask= ((analytic_events['section']==2) & ~(analytic_events['identifier'].str[0].str.isdigit().fillna(False)))
    【解决方案2】:

    您应该尝试在identifier 系列上使用str 属性,如下所示:

    sum((analytic_events[(analytic_events['section']==2)) & ~(analytic_events['identifier'].str[0].str.isdigit())].index)
    

    【讨论】:

      猜你喜欢
      • 2023-01-27
      • 2019-09-16
      • 2019-01-30
      • 1970-01-01
      • 2020-12-24
      相关资源
      最近更新 更多