Python 列中重复值之间的条件

Python 列中重复值之间的条件,python,pandas,pandas-groupby,loc,Python,Pandas,Pandas Groupby,Loc,当每个客户有多个计划时,他们都是重复的。我想设置客户的状态: 如果他们的每个产品都填写了“已取消”,则客户状态将被取消,但如果不是每个产品都填写了“已取消”,但至少有一个,则状态将为“降级”,因为他丢失了一个产品 customer|canceled_at|status x |3/27/2018 | x | | y |2/2/2018 | y |2/2/2018 | z |1/1/2018 | a

当每个客户有多个计划时,他们都是重复的。我想设置客户的状态:

如果他们的每个产品都填写了“已取消”,则客户状态将被取消,但如果不是每个产品都填写了“已取消”,但至少有一个,则状态将为“降级”,因为他丢失了一个产品

customer|canceled_at|status
x       |3/27/2018  |
x       |           |
y       |2/2/2018   |
y       |2/2/2018   |
z       |1/1/2018   |
a       |           |      
我已经有取消状态,现在我只需要降级

df['status']=(df.groupby('customer')['canceled_at'].
  transform(lambda x: x.notna().all()).map({True:'canceled'})).fillna(df.status)

这里可以比较列中的无缺失值,并按
系列
客户
和进行分组, 对于测试所有值
True
s(所有未缺失)或至少一个未缺失值(任何未缺失),并将其传递给:

或:


如果只有
NaN
s组需要转换为
降级

mask = df['canceled_at'].notna().groupby(df['customer']).transform('all')
df['status'] = np.where(mask,'canceled','downgrade')
print (df)
  customer canceled_at     status
0        x   3/27/2018  downgrade
1        x         NaN  downgrade
2        y    2/2/2018   canceled
3        y    2/2/2018   canceled
4        z    1/1/2018   canceled
5        a         NaN  downgrade  

以下是一种方法:

将熊猫作为pd导入
def选择_状态(已取消):
c=已取消。计数()
如果c==0:
状态=“”
elif c==len(已取消):
状态='已取消'
其他:
状态=‘降级’
返回pd.Series(状态,索引=已取消索引)
df=pd.DataFrame({'customer':['x','x','y','y','z','a'],
‘取消日期’:[‘2018年3月27日’,无、‘2018年2月2日’、‘2018年2月2日’、‘2018年1月1日’,无])
df['status']=df.groupby('customer')['cancelled'u at'].应用(选择状态)
打印(df)
输出:

客户已取消\u状态
0 x 2018年3月27日降级
1 x无降级
2018年2月2日取消
2018年2月2日取消
4 z 2018年1月1日取消
5 a无
g = df['canceled_at'].notna().groupby(df['customer'])
m1 = g.transform('all')
m2 = g.transform('any')

df['status'] = np.select([m1, m2],['canceled','downgrade'], np.nan)
print (df)
  customer canceled_at     status
0        x   3/27/2018  downgrade
1        x         NaN  downgrade
2        y    2/2/2018   canceled
3        y    2/2/2018   canceled
4        z    1/1/2018   canceled
5        a         NaN        nan
df['status'] = np.select([m1, m2],['canceled','downgrade'], '')
print (df)
  customer canceled_at     status
0        x   3/27/2018  downgrade
1        x         NaN  downgrade
2        y    2/2/2018   canceled
3        y    2/2/2018   canceled
4        z    1/1/2018   canceled
5        a         NaN         
mask = df['canceled_at'].notna().groupby(df['customer']).transform('all')
df['status'] = np.where(mask,'canceled','downgrade')
print (df)
  customer canceled_at     status
0        x   3/27/2018  downgrade
1        x         NaN  downgrade
2        y    2/2/2018   canceled
3        y    2/2/2018   canceled
4        z    1/1/2018   canceled
5        a         NaN  downgrade