有条件地顺序比较groupby值

n8-da-gr8

给定一个数据框

data = [['Bob','25'],['Alice','46'],['Alice','47'],['Charlie','19'],
['Charlie','19'],['Charlie','19'],['Doug','23'],['Doug','35'],['Doug','35.5']]

df = pd.DataFrame(data, columns = ['Customer','Sequence'])

计算以下内容:

  1. Sequence每个组中的一个被分配GroupID为1。
  2. 首先SequenceSequence每个组中的后续进行比较
  3. 如果差异大于.5,则增加GroupID
  4. 如果GroupID增加了,则不要使用后续值与第一个值进行比较,而使用current Sequence

在下面的期望结果表中...

  • 鲍勃只有1条记录,所以GroupID是1条。
  • 爱丽丝有2条记录,并且两个Sequence值(46&47)之差大于.5,因此该GroupID值递增。
  • 查理的Sequence值都相同,因此所有记录都为GroupID1。
  • 对于Doug,前两个Sequence值(23&35)之间的差大于.5,因此GroupID第二个值Sequence变为2。现在,由于增大了,因此GroupID我想将下一个值35.5与35比较,而不是23 ,这意味着最后两行共享相同的内容GroupID

所需结果:

顾客ID 顺序 组号
鲍勃 25 1个
爱丽丝 46 1个
爱丽丝 47 2
查理 19 1个
查理 19 1个
查理 19 1个
道格 23 1个
道格 35 2
道格 35.5 2

我的实现:

# generate unique ID based on each customers Sequence
df['EventID'] = df.groupby('Customer')[
                'Sequence'].transform(lambda x: pd.factorize(x)[0]) + 1

# impute first Sequence for each customer for comparison
df['FirstSeq'] = np.where(
    df['EventID'] == 1, df['Sequence'], np.nan
    )

# groupby and fill first Sequence forward
df['FirstSeq'] = df.groupby('Customer')[
    'FirstSeq'].transform(lambda v: v.ffill())

# get difference of first Sequence and all others
df['FirstSeqDiff'] = abs(df['FirstSeq'] - df['Sequence'])
    
# create unique GroupID based on Sequence difference from first Sequence
df["GroupID"] = np.cumsum(df.FirstSeqDiff > 0.5) + 1

上面的代码适用于Bob,Alice和Charlie这样的情况,但不适用于Doug,因为它总是与第一个进行比较SequenceSequence如果GroupID递增,如何修改代码以更改比较

编辑:数据框将始终按客户和序列进行排序。我猜想一个更好的方法来解释我的目标是为所有Sequence差异小于或等于0.5的值分配唯一的ID ,并按客户分组。

聂林哲

该代码有错误->添加df = df.astype({'Customer':str,'Sequence':np.float64})将解决该问题。但是仍然无法通过这种设计获得想要的东西。尝试定义自己的lambda函数myfunc,它可以直接解决您的问题:

data = [['Bob','25'],['Alice','46'],['Alice','47'],['Charlie','19'],
['Charlie','19'],['Charlie','19'],['Doug','23'],['Doug','35'],['Doug','35.5']]

df = pd.DataFrame(data, columns = ['Customer','Sequence'])
df = df.astype({'Customer':str,'Sequence':np.float64})

def myfunc(series):
    ret = []
    series = series.sort_values().values
    for i,val in enumerate(series):
        if i==0:
            ret.append(1)
        else:
            ret.append(ret[-1]+(series[i]-series[i-1]>0.5))
    return ret

df['EventID'] = df.groupby('Customer')[
                'Sequence'].transform(lambda x: myfunc(x))
print (df)

快乐编码我的朋友。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章