2017-09-15 171 views
0

我想重新列舉給定df中使用某些條件的行。我的問題是這個question的延伸。根據條件枚舉每個dtaaframe組的行

df示例:

ind seq status 
0 1 2 up 
1 1 3 mid 
2 1 5 down 
3 2 1 up 
4 2 2 mid 
5 2 3 down 
6 3 1 up 
7 3 2 mid 
8 3 3 oth 

df包含ind柱代表一個seq列可能有一些不良數據。這是這樣,我想補充另一列seq_corr根據一些條件來糾正seq枚舉:

  • status列一組中的第一個值等於up
  • status列一組中的最後一個值等於downoth
  • 在所有其他情況下從seq列拷貝數。

我知道這樣做的邏輯方法,但我有一些麻煩如何將其轉換爲Python。特別是當涉及適當的切片和訪問每個組的第一個和最後一個元素時。

下面你可以找到我的工作不代碼:

def new_id(x): 
    if (x.loc['status',0] == 'up') and ((x.loc['status',-1]=='down') or (x['status',-1]=='oth')): 
     x['ind_corr'] = np.arange(1, len(x) + 1) 
    else: 
     x['seq_corr']= x['seq'] 
    return x 

df.groupby('ind', as_index=False).apply(new_id) 

預期結果:

ind seq status seq_corr 
0 1 2 up  1 
1 1 3 mid  2 
2 1 5 down  3 
3 2 1 up  1 
4 2 2 mid  2 
5 2 3 down  3 
6 3 5 up  1 
7 3 2 mid  2 
8 3 7 oth  3 

希望有人能指出我的任何解決方案。

回答

1

讓我們試試df.groupby後跟applyconcatenat離子。

vals = df.groupby('ind').apply(
     lambda g: np.where(g['status'].iloc[0] == 'up' 
         or g['status'].iloc[-1] in {'down', 'oth'}, 
     np.arange(1, len(g) + 1), g['seq']) 
).values 

df['seq_corr'] = np.concatenate(vals) 

df 
    ind seq status seq_corr 
0 1 2  up   1 
1 1 3 mid   2 
2 1 5 down   3 
3 2 1  up   1 
4 2 2 mid   2 
5 2 3 down   3 
6 3 1  up   1 
7 3 2 mid   2 
8 3 3 oth   3 
+0

謝謝你的作品非常好!只是一個問題。如果我想在狀態不符合任何條件的情況下複製'seq'號碼,我該怎麼辦? – Michal

+0

@Michal用'和'簡單替換'或'。 – Dark

+0

@cᴏʟᴅsᴘᴇᴇᴅ我對你的答案做了一些修改。你可以用你的文字編輯它。 – Dark

1

與GROUPBY cumcount的另一種方法。要選擇第一行和最後一行,我們可以使用頭部和尾部方法併合並它們的索引。我覺得這個可能與你的第二個問題幫助

df['seq_corr'] = df.groupby('ind').cumcount()+1 
idx = df.groupby('ind').head(1).index.union(df.groupby('ind').tail(1).index) 

df.loc[idx,'seq_corr'] = np.where(~df.loc[idx,'status'].isin(['up','down','oth']), 
            df.loc[idx,'seq'],df.loc[idx,'seq_corr']) 

樣本輸出:

 
    ind seq status seq_corr 
0 1 2  up   1 
1 1 3 mid   2 
2 1 5 dance   5 
3 2 1  up   1 
4 2 2 mid   2 
5 2 3 down   3 
6 3 1  up   1 
7 3 2 mid   2 
8 3 3 oth   3 
+0

謝謝@Bharath shetty。 'inin([...])'是否考慮到所有使用'AND'語句的條件?我的想法是也有'或'。但無論如何,我已經合併@cᴏʟᴅsᴘᴇᴇᴅ答案與我的想法,它看起來像一切工作正常。我將在下面發佈解決方案。 – Michal

+0

由於我們正在分組數據的第一行和最後一行,因此這會根據您的「OR」條件正常工作。這是期望的輸出權利?你面臨的任何問題? – Dark

0

感謝@cᴏʟᴅsᴘᴇᴇᴅ我已經改正了我的代碼。看第一次測試,一切都很好。

def new_id(x): 
    if (x['status'].iloc[0] == 'up') and ((x['status'].iloc[-1]=='down') or (x['status'].iloc[-1]=='oth')): 
    x['seq_corr'] = np.arange(1, len(x) + 1) 
    else: 
    x['seq_corr']= x['seq'] 
    return x