我有一个如下的数据框df
ZMONTH GROUP ORDER_QTY
201907 A 25
201908 A 23
201909 A 24
201907 B 15
201908 B 0
201909 B 0
我要根据以下条件添加另一列ACTIVE
:
if ORDER_QTY of last two rows for each group is 0, then ACTIVE==0 else 1
因此,结果df_f
看起来像
ZMONTH GROUP ORDER_QTY ACTIVE
201907 A 25 1
201908 A 23 1
201909 A 24 1
201907 B 15 0
201908 B 0 0
201909 B 0 0
根据上述逻辑,我尝试了以下方法
def active_field(row):
if row.loc[row['ZMONTH']=='201909','ORDER_QTY']==0:
val=0
elif row.loc[row['ZMONTH']=='201908','ORDER_QTY']==0:
val=0
else:
val=1
return val
df['ACTIVE'] = df.apply(active_field,axis=1)
以上代码给出了IndexingError: Too many indexers
错误。
我在哪里想念?
答案 0 :(得分:1)
您可以groupby
并检查每组最后两行是否相等,然后对布尔结果取all
。然后只需将生成的布尔数组视为int8
并将它们分配给ACTIVE
:
df['ACTIVE'] = (df.groupby('GROUP').ORDER_QTY
.transform(lambda x: x.tail(2).ne(0).any())
.view('i1'))
print(df)
ZMONTH GROUP ORDER_QTY ACTIVE
0 201907 A 25 1
1 201908 A 23 1
2 201909 A 24 1
3 201907 B 15 0
4 201908 B 0 0
5 201909 B 0 0
答案 1 :(得分:1)
如果所有值都是numpy.where
的0
,则使用Series.all
来测试每组最后2个值:
s = df.groupby('GROUP')['ORDER_QTY'].transform(lambda x: x.tail(2).eq(0).all())
df['ACTIVE'] = np.where(s, 0, 1)
print (df)
ZMONTH GROUP ORDER_QTY ACTIVE
0 201907 A 25 1
1 201908 A 23 1
2 201909 A 24 1
3 201907 B 15 0
4 201908 B 0 0
5 201909 B 0 0
答案 2 :(得分:1)
我们也可以使用DataFrame.pivot
。
df['ACTIVE'] = (df['GROUP'].map(df.pivot(*df)[::-1].cumsum().iloc[1].ne(0))
.astype('int'))
print(df)
ZMONTH GROUP ORDER_QTY ACTIVE
0 201907 A 25 1
1 201908 A 23 1
2 201909 A 24 1
3 201907 B 15 0
4 201908 B 0 0
5 201909 B 0 0