样本DF:
ID Name Price Sum
1 Apple 10 180
2 Apple 10 100
3 Apple 10 80
4 Orange 12 180
5 Orange 12 190
6 Banana 15 50
7 Banana 15 30
预期DF:
ID Name Price Sum Result
1 Apple 10 180 Full Match
2 Orange 12 180 Match - High Confidence
3 Orange 12 190 Match - High Confidence
4 Banana 15 50 Match - Low Confidence
5 Banana 15 30 Match - Low Confidence
问题陈述:
我需要一个Result
列,它可以在以下条件下工作:
使用Name
和Price
组,即如果最高值不是 Apple 和Price 10 与其他人进行strong> +-30范围,然后保留结果列为Full Match
的最高值行,并删除其他人(样本Df-ID 1,2,3,预期DF仅是ID 1)
在Name
和Price
组中,如果它们在 +-30范围内,并且也大于100,则结果列将为Match - High Confidence
并且没有行被删除(示例Df-ID 4,5,预期DF为ID 2,3)
在Name
和Price
组中(如果它在 +-30范围内)并且小于60,则结果列将为Match - Low Confidence
和没有行被删除(示例Df-ID 6,7,预期DF为ID 4,5)
当涉及的组加上范围的组合时,我无法找到任何解决方法。有帮助吗?
答案 0 :(得分:1)
这是我想出的,您可以尝试一下:
#get absolute difference from max value
df['diff_abs']=abs(df.Sum-df.groupby(['Name','Price'])['Sum'].transform('max'))
#check if diff less than 30 remove them
m=df.loc[df.duplicated(['Name','Price'],keep=False)&df.diff_abs.lt(30)].reset_index()
print(m)
index ID Name Price Sum diff_abs
0 0 1 Apple 10 180 0
1 3 4 Orange 12 180 10
2 4 5 Orange 12 190 0
3 5 6 Banana 15 50 0
4 6 7 Banana 15 30 20
c1=~m.duplicated(['Name','Price'],keep=False) #check if entry is just 1 and no dups
c2=m.duplicated(['Name','Price'],keep=False)&m.Sum.lt(60) #if dups check for less than 60
m['result']=np.select([c1,c2],\
['Full Match','Match - Low Confidence'],'Match - High Confidence')
print(m)
index ID Name Price Sum diff_abs result
0 0 1 Apple 10 180 0 Full Match
1 3 4 Orange 12 180 10 Match - High Confidence
2 4 5 Orange 12 190 0 Match - High Confidence
3 5 6 Banana 15 50 0 Match - Low Confidence
4 6 7 Banana 15 30 20 Match - Low Confidence
答案 1 :(得分:1)
我认为您需要:
#get Series for maximal value of group
maxpergroup = df.groupby(['Name','Price'])['Sum'].transform('max')
#subtract values, get absolute values and compare by greater 30
m1 = df['Sum'].sub(maxpergroup).abs().gt(30)
#get all groups where at least one True
m11 = m1.groupby([df['Name'],df['Price']]).transform('any')
#print (m11)
#compare by another values and test if all values matching per groups
m2 = df['Sum'].gt(100)
m22 = (m2 & ~m1).groupby([df['Name'],df['Price']]).transform('all')
#print (m22)
m3 = df['Sum'].lt(60)
m33 = (m3 & ~m1).groupby([df['Name'],df['Price']]).transform('all')
#print (m33)
#create new column
masks = [m11,m22, m33]
vals = ['Full Match','Match - Low Confidence','Match - High Confidence']
df['result'] = np.select(masks, vals)
#remove unnecessary rows
df = df[~m11 | df['Sum'].eq(maxpergroup)]
print (df)
ID Name Price Sum result
0 1 Apple 10 180 Full Match
3 4 Orange 12 180 Match - Low Confidence
4 5 Orange 12 190 Match - Low Confidence
5 6 Banana 15 50 Match - High Confidence
6 7 Banana 15 30 Match - High Confidence