如何获得此输出?

时间:2019-07-18 05:19:58

标签: python-3.x pandas dataframe

我有一个很大的Pandas Data Frame。其中一部分看起来像这样:

 Rule_Name Rule_Seq_No  Condition Expression  Type   

Rule P     1            ID         19909       Action      
Rule P     1            Type       A           Condition   
Rule P     1            System     B           Condition   
Rule P     2            ID         19608       Action      
Rule P     2            Type       A           Condition  
Rule P     2            System     C           Condition   
Rule S     1            ID         19909       Action      
Rule S     1            Type       A           Condition   
Rule S     1            System     M           Condition   
Rule S     2            ID         19608       Action     
Rule S     2            Type       C           Condition   
Rule S     2            System     F           Condition 

此表包含一些带有序列号的规则。

我尝试使用不同的功能,例如MERGEGROUP BYAPPLY,但没有得到所需的输出。

期望的输出应该是这样的:

 Rule_Name  Rule_Seq_No        Condition          Action  

Rule P       1            (Type=A)and(System=B)    19909   
Rule P       2            (Type=A)and(System=C)    19608   
Rule S       1            (Type=A)and(System=M)    19909   
Rule S       2            (Type=A)and(System=F)    19608 

对于相同的规则和相同的序列号,以及TYPECondition的地方,我想合并行。而且,在TYPEACTION的地方,它应该显示在单独的列中。

1 个答案:

答案 0 :(得分:4)

使用:

df1 = (df.assign(Condition = '(' + df['Condition'] + '=' + df['Expression'] + ')')
         .groupby(['Rule_Name','Rule_Seq_No','Type'])
         .agg({'Condition': 'and'.join, 'Expression':'first'})
         .unstack()
         .drop([('Condition','Action'), ('Expression','Condition')], axis=1)
         .droplevel(axis=1, level=0)
         .reset_index()
         .rename_axis(None, axis=1))
print (df1)
  Rule_Name  Rule_Seq_No              Condition Action
0    Rule P            1  (Type=A)and(System=B)  19909
1    Rule P            2  (Type=A)and(System=C)  19608
2    Rule S            1  (Type=A)and(System=M)  19909
3    Rule S            2  (Type=C)and(System=F)  19608

说明

  1. 将列ConditionExpression=结合在一起并添加()
  2. 通过GroupBy.aggjoinfirst进行
  3. DataFrame.unstack重塑
  4. 通过DataFrame.drop用元组删除不必要的列,因为MultiIndex
  5. 通过DataFrame.droplevelMultiIndex的最高级别删除
  6. 通过DataFrame.reset_indexDataFrame.rename_axis清理数据

编辑:

使用Index.droplevel的大熊猫版本(低于0.24+)的解决方案:

df1 = (df.assign(Condition = '(' + df['Condition'] + '=' + df['Expression'] + ')')
         .groupby(['Rule_Name','Rule_Seq_No','Type'])
         .agg({'Condition': 'and'.join, 'Expression':'first'})
         .unstack()
         .drop([('Condition','Action'), ('Expression','Condition')], axis=1))

df1.columns = df1.columns.droplevel(level=0)
df1 = df1.reset_index().rename_axis(None, axis=1)
print (df1)
  Rule_Name  Rule_Seq_No              Condition Action
0    Rule P            1  (Type=A)and(System=B)  19909
1    Rule P            2  (Type=A)and(System=C)  19608
2    Rule S            1  (Type=A)and(System=M)  19909
3    Rule S            2  (Type=C)and(System=F)  19608