【问题标题】:Count of values per row that do not satisfy a condition每行不满足条件的值的计数
【发布时间】:2019-06-19 03:56:05
【问题描述】:

我想比较1/01列中的值, 1/02,1/03,1/04,1/05,1/06 与目标列中的值一起使用criteria 列中的条件。我想获取 Sum 列中每个 ID 不符合条件的所有值的计数。

# importing pandas as pd 
import pandas as pd 

# Create sample dataframe
 raw_data = {'ID': ['A1', 'B1', 'C1', 'D1'], 
'Domain': ['Finance', 'IT', 'IT', 'Finance'], 
'Target': [1, 2, 3, 1], 
'Criteria':['<=', '<=', '>=', '>='],
"1/01":[0.9, 1.1, 2.1, 1],
"1/02":[0.4, 0.3, 0.5, 0.9], 
"1/03":[1, 1, 4, 1.1], 
"1/04":[0.7, 0.7, 0.1, 1],
"1/05":[0.7, 0.7, 0.1, 1], 
"1/06":[0.9, 1.1, 2.1, 1],}



 df = pd.DataFrame(raw_data, columns = ['ID', 'Domain', 'Target','Criteria', '1/01', 
'1/02','1/03', '1/04','1/05', '1/06','Sum'])

预期输出示例:

   ID   Domain  Target Criteria  1/01  1/02  1/03  1/04  1/05  1/06  Sum
0  A1  Finance       1       <=   0.9   0.4   1.0   0.7   0.7   0.9  0.0
1  B1       IT       2       <=   1.1   0.3   1.0   0.7   0.7   1.1  0.0
2  C1       IT       3       >=   2.1   0.5   4.0   0.1   0.1   2.1  5.0
3  D1  Finance       1       >=   1.0   0.9   1.1   1.0   1.0   1.0  1.0

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    只需使用np.where 选择性地计算违反标准的行。这针对 = 作为唯一可能标准的问题进行了优化。

    # `.to_numpy()` will work for pandas versions >= 0.24. 
    # For older versions, use .values.
    dates = df.iloc[:,4:].to_numpy()
    target = df[['Target']].to_numpy()
    
    df['Sum'] = np.where(
      (df['Criteria'] == '<=')[:,None], dates > target, dates < target).sum(axis=1)
    df
    
       ID   Domain  Target Criteria  1/01  1/02  1/03  1/04  1/05  1/06  Sum
    0  A1  Finance       1       <=   0.9   0.4   1.0   0.7   0.7   0.9    0
    1  B1       IT       2       <=   1.1   0.3   1.0   0.7   0.7   1.1    0
    2  C1       IT       3       >=   2.1   0.5   4.0   0.1   0.1   2.1    5
    3  D1  Finance       1       >=   1.0   0.9   1.1   1.0   1.0   1.0    1
    

    【讨论】:

    • 它现在可以工作了,我只是做了一个改变。而不是 dates = df.filter(regex=r'\d/\d{2}').to_numpy() 我做了 dates = df.iloc[:,4:].values
    • @krijan 太好了,这意味着 Sum 列也应该预先删除(或者根本不存在,对吧?)。
    • 正确,这只是日期的错误,我猜他们没有在 excel 文件中以正确的格式放置日期,这就是函数无法识别日期列的原因。所以我们不得不做 iloc 的方式并提取所有的日期列。 :)
    【解决方案2】:

    想法是使用operators 按过滤行进行比较,通过DataFrame.mask 获取不匹配的值,最后通过分配给新列的sum - 此操作由字典中的所有运算符循环:

    import operator
    
    
    ops = { '>=': operator.lt,
           '<=': operator.gt}
    
    for k, v in ops.items():
        mask = df['Criteria'].eq(k).values
        df1 = df.iloc[mask, 4:]
        df.loc[mask, 'new'] = (v)(df1,df.loc[mask, 'Target'].values[:, None]).sum(axis=1)
    print (df)
       ID   Domain  Target Criteria  1/01  1/02  1/03  1/04  1/05  1/06  Sum  new
    0  A1  Finance       1       <=   0.9   0.4   1.0   0.7   0.7   0.9  0.0  0.0
    1  B1       IT       2       <=   1.1   0.3   1.0   0.7   0.7   1.1  0.0  0.0
    2  C1       IT       3       >=   2.1   0.5   4.0   0.1   0.1   2.1  5.0  5.0
    3  D1  Finance       1       >=   1.0   0.9   1.1   1.0   1.0   1.0  1.0  1.0
    

    【讨论】:

    • 您好,感谢您的回答。对此,我真的非常感激。但是,“新建”列应该输出,有多少值不符合条件。示例:对于 ID C1,我们的目标是 3,标准是 '>=' 表示 3。对于日期列,我们只有 1 个值,即 '>=' 到 3,其值为 4。那么输出应该是 1。因为它只有 1 个值,即 '>=' 到 3。因此,基本上我想知道我怎么能做到这一点:) 请。
    • 我解决了我的问题,您可以看到我需要的预期输出,希望对您有所帮助:)。
    • @krijan - 所以标准只有 &lt;= 和 &lt;= ?
    • @krijan - 是的,所以criteria 列中只有&lt;= 和&gt;= 值?
    猜你喜欢
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    相关资源
    最近更新 更多