2017-09-15 125 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