每行不满足条件的值计数

时间:2019-06-19 03:56:05

标签: python pandas dataframe

我想比较1/01列中的值, 1/021/031/041/051/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

2 个答案:

答案 0 :(得分:1)

想法是使用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

答案 1 :(得分: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