2017-07-23 52 views
1

这是作为一个数据帧的子集总结了大熊猫数据:通过分组数据

  drug_id   A B C  type 
     lexapro.13  1    SSRI   
     lexapro.13  1  1  SSRI  
     lexapro.13   1   SSRI  
     lexapro.13   1   SSRI 
     effexor.223    1  SNRI 
     effexor.223   1   SNRI  
     cymbalta.18    1  SNRI  
     cymbalta.18  1    SNRI 

正如所看到的,该药物ID重复,但是对于A,B和C的值是不同的。首先,我需要通过drug_id对数据进行分组,如果该组的任何行中的A(例如lexapro.13)的值为“1”,则该组中的A的值为“1”,否则将得到0。如果该组的任何行中的IFB具有值“1”,那么该组中的B将接收“1”,否则将得到0,并且对于“C”是相同的。输出应该是这样的:

 drug_id   A B C type 
     lexapro.13  1 1 1 SSRI   
     effexor.223  0 1 1 SNRI  
     cymbalta.18  1 0 1 SNRI   

我想起初我需要通过使用set_index的drug_id列对数据进行分组,然后在该组的列A中搜索值1,在该组中的列B的值为1,而对于C也是如此。但是,我没有知道如何去做。任何建议?

+0

可能一些其他数据如'1',''中A,B,C'列NaN's? – jezrael

+0

是的,有可能 – Mary

回答

3

你可以使用groupby和聚合max,然后通过fillna通过astype取代NaN S,转换为int S和持续如果从index需要列添加reset_index

df = df.groupby('drug_id', sort=False).max().fillna(0).astype(int).reset_index() 
print (df) 
     drug_id A B C 
0 lexapro.13 1 1 1 
1 effexor.223 0 1 1 
2 cymbalta.18 1 0 1 

另一种解决方案与any检查是否至少一个值不是zeroNaN每组和每列:

df = df.groupby('drug_id', sort=False).any().fillna(0).astype(int).reset_index() 
print (df) 
     drug_id A B C 
0 lexapro.13 1 1 1 
1 effexor.223 0 1 1 
2 cymbalta.18 1 0 1 

如果需要检查只1值在所有colums没有drug_id有可能得到的所有列名w ^第i个difference然后eq1比较:

cols = df.columns.difference(['drug_id']) 
df[cols] = df[cols].eq(1).astype(int) 

df = df.groupby('drug_id', sort=False).max().reset_index() 
#or 
#df = df.groupby('drug_id', sort=False).any().reset_index() 

编辑:

如果有另一个text列,需要agg骨料每一列,其他列被遗漏。

d = {'A': [3.0, 1.0, np.nan, np.nan, np.nan, np.nan, np.nan, 1.0], 
    'type': ['SSRI1', 'SSRI2', 'SSRI3', 'SSRI4', 'SNRI5', 'SNRI6', 'SNRI7', 'SNRI8'], 
    'drug_id': ['lexapro.13', 'lexapro.13', 'lexapro.13', 
       'lexapro.13', 'effexor.223', 'effexor.223', 'cymbalta.18', 'cymbalta.18'], 
    'B': [np.nan, np.nan, 1.0, 1.0, np.nan, 5.0, 4.0, 1.0], 
    'C': [np.nan, 1.0, np.nan, np.nan, 1.0, np.nan, 2.0, np.nan]} 
df = pd.DataFrame(d, columns=['drug_id', 'A', 'B', 'C', 'type']) 
print (df) 
     drug_id A B C type 
0 lexapro.13 3.0 NaN NaN SSRI1 
1 lexapro.13 1.0 NaN 1.0 SSRI2 
2 lexapro.13 NaN 1.0 NaN SSRI3 
3 lexapro.13 NaN 1.0 NaN SSRI4 
4 effexor.223 NaN NaN 1.0 SNRI5 
5 effexor.223 NaN 5.0 NaN SNRI6 
6 cymbalta.18 NaN 4.0 2.0 SNRI7 
7 cymbalta.18 1.0 1.0 NaN SNRI8 

校验值1

cols = df.columns.difference(['drug_id', 'type']) 
df[cols] = df[cols].eq(1).astype(int) 
print (df) 
     drug_id A B C type 
0 lexapro.13 0 0 0 SSRI1 
1 lexapro.13 1 0 1 SSRI2 
2 lexapro.13 0 1 0 SSRI3 
3 lexapro.13 0 1 0 SSRI4 
4 effexor.223 0 0 1 SNRI5 
5 effexor.223 0 0 0 SNRI6 
6 cymbalta.18 0 0 0 SNRI7 
7 cymbalta.18 1 1 0 SNRI8 

动态准备字典 - 为type需要另一个功能列。 使用first为每组或join第一值对于所有的值以string的所有值:

d = {x:'max' for x in cols} 
d['type'] = 'first' 
print (d) 
{'A': 'max', 'type': 'first', 'B': 'max', 'C': 'max'} 

df1 = df.groupby('drug_id', sort=False).agg(d).reset_index().reindex_axis(df.columns, axis=1) 
print (df1) 
     drug_id A B C type 
0 lexapro.13 1 1 1 SSRI1 
1 effexor.223 0 0 1 SNRI5 
2 cymbalta.18 1 1 0 SNRI7 

d = {x:'max' for x in cols} 
d['type'] = ', '.join 
print (d) 
{'A': 'max', 'type': <built-in method join of str object at 0x000000000B447340>, 
'B': 'max', 'C': 'max'} 

df2 = df.groupby('drug_id', sort=False).agg(d).reset_index().reindex_axis(df.columns, axis=1) 
print (df2) 
     drug_id A B C      type 
0 lexapro.13 1 1 1 SSRI1, SSRI2, SSRI3, SSRI4 
1 effexor.223 0 0 1    SNRI5, SNRI6 
2 cymbalta.18 1 1 0    SNRI7, SNRI8 
+0

你能解释一下max()和reset_index()是如何工作的吗? – Mary

+0

谢谢,你为什么排序为“假”? – Mary

+0

'max'选择每个组的最大值和汇总数据。我首先添加'sort = False'来不排序groupbig列'drug_id',所以您需要的输出相同。如果省略它,订单仅有不同。 – jezrael