2017-03-08 43 views
0

有以下數據幀df計數行:我計算每ID_DATA頻率如下如何而嵌合一些規則

df = 

ID_DATA FD_1 FD_2 FD_3 FD_4 GRADE 
111  23  12  34  45  1 
111  23  67  45   5 
111  12  67  45  23  5 
222  23  55  66   4 
222  55  66     4 

freq = df.ID_DATA.value_counts().reset_index() 

freq = 

ID_DATA FREQ 
111  3 
222  2 

然而,我需要改變邏輯這個計算如下。有兩個清單的FD_*不同的值:

BaseList = [23,34] 
AdjList = [12,45,67] 

我需要計算這兩個列表值的出現的頻率df。但有一些規則:

1)如果一行包含任何值FD_*屬於AdjList,則不應計算BaseListBaseList的計數只能在行不包含任何來自AdjList的值時完成。

2)如果一行包含多個值BaseList,那麼它應該計爲+1。 3)如果一行包含多個值AdjList,那麼只應計數最後一列FD_*

結果應該是這一個:

ID_DATA FREQ_BaseList FREQ_12 FREQ_45 FREQ_67 
111  0    0   3   0 
222  1    0   0   0 

FREQ_BaseList的值是因爲擊發規則#1的等於0 111,。

回答

1

想法是爲此創建自定義函數,然後根據需要進行調整。您當然可以通過替換列的硬編碼列表使其更漂亮:

>>> def worker1(x): 
...  b = 0 
...  for v in x: 
...   if v in AdjList: 
...    return ['FREQ_' + str(int(v)), 1] 
...   else: 
...    b = b + BaseList.count(v) 
...  return ('FREQ_BaseList', b) 
... 
>>> def worker2(x): 
...  r = worker1(x[['FD_4','FD_3','FD_2','FD_1']]) 
...  return pd.Series([x['ID_DATA'], r[1]], index=['ID_DATA', r[0]]) 
... 
>>> res = df.apply(worker2, axis=1).groupby('ID_DATA').sum() 
>>> res 
     FREQ_45 FREQ_BaseList 
ID_DATA       
111.0  3.0   NaN 
222.0  NaN   1.0 
>>> res.reindex(columns=['FREQ_BaseList','FREQ_12','FREQ_45','FREQ_67']).fillna(0).astype(int) 
     FREQ_BaseList FREQ_12 FREQ_45 FREQ_67 
ID_DATA           
111.0    0  0  3  0 
222.0    1  0  0  0