2017-07-23 51 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