我想比较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
答案 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