带字符串的多层if语句

时间:2019-11-05 17:16:44

标签: python pandas if-statement

我有一个数据框

df = pd.DataFrame([[3,2,1,5,'Stay',2],[4,5,6,10,'Leave',10],
                   [10,20,30,40,'Stay',11],[12,2,3,3,'Leave',15],
                   [31,23,31,45,'Stay',25],[12,21,17,6,'Stay',15],
                   [15,17,18,12,'Leave',10],[3,2,1,5,'Stay',3],
                   [12,2,3,3,'Leave',12]], columns = ['A','B','C','D','Status','E'])


    A   B   C   D Status   E
0   3   2   1   5   Stay   2
1   4   5   6  10  Leave  10
2  10  20  30  40   Stay  11
3  12   2   3   3  Leave  15
4  31  23  31  45   Stay  25
5  12  21  17   6   Stay  15
6  15  17  18  12  Leave  10
7   3   2   1   5   Stay   3
8  12   2   3   3  Leave  12

我想运行一个条件,如果状态为Stay且如果E列小于A列,则:更改数据,其中D列中的数据替换为C列,C列中的数据替换为B列中的数据被替换为A列中的数据,B列中的数据被替换为E列中的数据。 如果“状态”为“离开”,并且如果E列大于A列,则:更改数据,其中D列中的数据替换为C列数据,C列中的数据替换为B列中的数据,B列中的数据替换为A列中的数据和A列中的数据将替换为E列中的数据。

结果是:

    A   B   C   D Status   E
0   2   3   2   1   Stay   2
1  10   4   5   6  Leave  10
2  10  20  30  40   Stay  11
3  15  12   2   3  Leave  15
4  25  31  23  31   Stay  25
5  12  21  17   6   Stay  15
6  15  17  18  12  Leave  10
7   3   2   1   5   Stay   3
8  12   2   3   3  Leave  12

我的尝试

if df['Status'] == 'Stay':
    if df['E'] < df['A']:
        df['D'] = df['C']
        df['C'] = df['B']
        df['B'] = df['A']
        df['A'] = df['E']
elif df['Status'] == 'Leave':
        if df['E'] > df['A']:
        df['D'] = df['C']
        df['C'] = df['B']
        df['B'] = df['A']
        df['A'] = df['E']

这会遇到很多问题,包括字符串问题。非常感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

我认为您想要布尔索引:

s1 = df.Status.eq('Stay') & df['E'].lt(df['A'])
s2 = df.Status.eq('Leave') & df['E'].gt(df['A'])
s = s1 | s2
df.loc[s, ['A','B','C','D']] = df.loc[s, ['E','A','B','C']].to_numpy()

输出:

    A   B   C   D Status   E
0   2   3   2   1   Stay   2
1  10   4   5   6  Leave  10
2  10  20  30  40   Stay  11
3  15  12   2   3  Leave  15
4  25  31  23  31   Stay  25
5  12  21  17   6   Stay  15
6  15  17  18  12  Leave  10
7   3   2   1   5   Stay   3
8  12   2   3   3  Leave  12

答案 1 :(得分:2)

np.roll.loc一起使用:

shift = np.roll(df.select_dtypes(exclude='object'),1,axis=1)[:, :-1]

m1 = df['Status'].eq('Stay') & (df['E'] < df['A'])
m2 = df['Status'].eq('Leave') & (df['E'] > df['A'])

df.loc[m1|m2, ['A','B','C','D']] = shift[m1|m2]

    A   B   C   D Status   E
0   2   3   2   1   Stay   2
1  10   4   5   6  Leave  10
2  10  20  30  40   Stay  11
3  15  12   2   3  Leave  15
4  25  31  23  31   Stay  25
5  12  21  17   6   Stay  15
6  15  17  18  12  Leave  10
7   3   2   1   5   Stay   3
8  12   2   3   3  Leave  12

答案 2 :(得分:2)

使用DataFrame.mask + DataFrame.shift

#Status like index to use shift
new_df=df.set_index('Status')
#DataFrame to replace
df_modify=new_df.shift(axis=1,fill_value=df['E'])
#Creating boolean mask
under_mask=(df.Status.eq('Stay'))&(df.E<df.A)
over_mask=(df.Status.eq('Leave'))&(df.E>df.A)
#Using DataFrame.mask
new_df=new_df.mask(under_mask|over_mask,df_modify).reset_index()



print(new_df)

输出

  Status   A   B   C   D   E
0   Stay   2   3   2   1   5
1  Leave  10   4   5   6  10
2   Stay  10  20  30  40  11
3  Leave  15  12   2   3   3
4   Stay  25  31  23  31  45
5   Stay  12  21  17   6  15
6  Leave  15  17  18  12  10
7   Stay   3   2   1   5   3
8  Leave  12   2   3   3  12

答案 3 :(得分:0)

听起来您想对数据的每一行都执行此操作,但是您的代码被编写为试图在顶层执行此操作。您可以使用for ... in循环遍历行吗?

for row in df:
    if row['Status'] == 'Stay':
        ... etc ...