2016-02-28 150 views
4

我有一個數據框,有一列,我想groupby。在每個組中,我想執行檢查以查看第一個值是否小於第二個值乘以某個標量,例如, (x < y * .5)。如果是,則第一個值設置爲True,所有其他值爲False。否則,所有的值都是假的。熊貓集團指數

我這裏有一個簡單的數據幀:

d = pd.DataFrame(np.array([[0, 0, 1, 1, 2, 2, 2], 
          [3, 4, 5, 6, 7, 8, 9], 
          [1.25, 10.1, 2.3, 2.4, 1.2, 5.5, 5.7]]).T, 
          columns=['a', 'b', 'c']) 

我可以得到一個堆疊GROUPBY得到,我想出來的數據a:這導致三組

g = d.groupby('a')['c'].nsmallest(2).groupby(level='a') 

,每個有2個條目。通過添加apply,我可以調用一個函數返回一個布爾面膜:

def func(group): 
    if group.iloc[0] < group.iloc[1] * .5: 
     return [True, False] 
    else: 
     return [False, False] 

g = d.groupby('a')['c'].nsmallest(2).groupby(level='a').apply(func) 

不幸的是,這會破壞指數爲原始數據幀,並刪除處理,其中2個以上元素存在的情況下的能力。

兩個問題:

  1. 是否有可能維持在原來的數據幀索引並更新了GROUPBY結果列?由於.nsmallest調用結果爲'c'列中的一個系列,因此稍有不同。

  2. 是否存在更優雅的方法來根據某些自定義條件(例如,自定義條件)爲數據框中的組計算布爾數組。這個比例測試。

回答

2

看起來transform是你所需要的:

>>> def func(group): 
...  res = [False] * len(group) 
...  if group.iloc[0] < group.iloc[1] * .5: 
...   res[0] = True 
...  return res 
>>> d['res'] = d.groupby('a')['c'].transform(func).astype('bool') 
>>> d 
    a b  c res 
0 0 3 1.25 True 
1 0 4 10.10 False 
2 1 5 2.30 False 
3 1 6 2.40 False 
4 2 7 1.20 True 
5 2 8 5.50 False 
6 2 9 5.70 False 

從文檔:

的變換方法返回一個索引相同(相同 大小)的對象爲一個被分組。因此,傳遞的變換函數 應該返回與組塊大小相同的結果。例如,對於 示例,假設我們希望將每個組內的數據標準化爲

+0

按廣告方式工作。我還沒有意識到,轉換可以採取任意功能(在文檔中錯過了它)。謝謝! – Jzl5325