根据条件使用现有列中的值将两个新列追加到datframe

时间:2019-09-27 12:02:38

标签: python pandas lambda

说,我有一个看起来像的数据框。

 df.head()
    ID  col1    col2    col3    col4    type
    1   146       91      Rp    Rp-203  ex
    1   146      314      Rp    Rp-203  trans
    1   603       91      Rp    Rp-203  CDS
    1   910       81      Rp    Rp-203  CDS
    1   910       81      Rp    Rp-203  ex
    1   202      825      Rp    Rp-203  CDS
    1   202      837      Rp    Rp-203  ex
    1   200      314      Rp    Rp-203  ex

根据以上数据框,我想生成数据框。数据帧基于type列等于ex的条件。除此之外,新的数据帧还应该具有另外两个列,其值基于col1col2以逗号分隔。

我想使用col5col6中每个值的col1col2中的值生成两列col4type列。 也就是说,我要在col3列的ex列中分组(type)。

最后,我希望将数据帧设置为

ID  col1    col2    col3    col4    ex_start    ex_end
1   146     314     Rp      Rp-203  091,081,837 910,202,200

我尝试了以下解决方案

df2 = df.loc[df['type']=='ex', ['col3','col1', 'col2',]].groupby(['col3']).agg(
        lambda x: ','.join([str(y) for y in x]))

但是,我的解决方案是将col1的第一个值捕获为ex_start的第一个值。但是我需要col2值作为ex_start的{​​{1}}列中的第一个值。并且df2值是col1ex_end列的第一个值,依此类推。 并且df2中的col1col2列应采用df2dfcol1中的值(如果列{{1} }等于col2

非常感谢您的帮助/建议!

2 个答案:

答案 0 :(得分:1)

使用:

#filter only ex rows by type
df3 = df[df['type']=='ex'].copy()

#shift values per groups from list
df3['s'] = df3.groupby(['ID','col3', 'col4'])['col2'].shift()
#removed NaNs rows per start and convert values to int and strings
df3 = df3.dropna(subset=['s']).assign(ex_start = lambda x: x['s'].astype(int).astype(str),
                                      ex_end = lambda x: x['col1'].astype(str))
print (df3)
   ID  col1  col2 col3    col4 type      s ex_start ex_end
4   1   910    81   Rp  Rp-203   ex   91.0       91    910
6   1   202   837   Rp  Rp-203   ex   81.0       81    202
7   1   200   314   Rp  Rp-203   ex  837.0      837    200

#then aggregate join
df4 = df3.groupby(['ID','col3', 'col4'])['ex_start','ex_end'].agg(','.join).reset_index()
print (df4)
   ID col3    col4   ex_start       ex_end
0   1   Rp  Rp-203  91,81,837  910,202,200

#filter by trans first rows per groups
df5 = df[df['type']=='trans'].drop_duplicates(['ID','col3', 'col4']).drop('type', 1)
print (df5)
   ID  col1  col2 col3    col4
1   1   146   314   Rp  Rp-203

#and add df5
df = df5.merge(df4)
print (df)
   ID  col1  col2 col3    col4   ex_start       ex_end
0   1   146   314   Rp  Rp-203  91,81,837  910,202,200

答案 1 :(得分:1)

这是我使用groupby和要处理的功能的方法

def join(group):
    ex = group[["col1", "col2"]].copy().values
    row = group.iloc[0]
    row[["col1", "col2"]] = (ex[0,0], ex[-1,1])
    row["ex_start"] = ",".join(ex[1:,0].astype(str))
    row["ex_end"] = ",".join(ex[:-1,1].astype(str))

    return row

df.groupby("type").apply(join)

仅获得您能获得的ex行

df.groupby("type").apply(join).loc[["ex"]]

输出

ID  col1    col2    col3    col4    type    ex_start    ex_end
type                                
CDS 1   603 825 Rp  Rp-203  CDS 910,202 91,81
ex  1   146 314 Rp  Rp-203  ex  910,202,200 91,81,837
trans   1   146 314 Rp  Rp-203  trans