2015-09-08 92 views
1

假設我有一個數據幀,看起來像這樣:在大熊貓數據幀選擇從內部基團的特定行

group level 
0  1  10 
1  1  10 
2  1  11 
3  2  5 
4  2  5 
5  3  9 
6  3  9 
7  3  9 
8  3  8 

所需的輸出是這樣的:

group level 
0  1  10 
5  3  9 

即,這是邏輯:看在每個組內部,如果level列中存在多個不同的值,則返回該組中的第一行。例如,沒有選擇來自組2的行,因爲level列中存在的唯一值是5

另外,如果我想要最後一個,而不是第一排這樣的組,那麼情況會如何變化?

我試圖將group_by語句與level列中條目的創建集結合起來,但未能產生甚至幾乎不明智的東西。

回答

2

這可以用groupby進行,並使用apply運行對每個組一個簡單的函數:

def get_first_val(group): 
    has_multiple_vals = len(group['level'].unique()) >= 2 
    if has_multiple_vals: 
     return group['level'].loc[group['level'].first_valid_index()] 
    else: 
     return None 

df.groupby('group').apply(get_first_val).dropna() 
Out[8]: 
group 
1 10 
3  9 
dtype: float64 

還有一個last_valid_index()方法,這樣你就不必 作出任何巨大的變化,以獲得最後一行。

如果你有,你想保留等欄目,你只需要輕微的調整:

import numpy as np 
df['col1'] = np.random.randint(10, 20, 9) 
df['col2'] = np.random.randint(20, 30, 9) 
df 
Out[17]: 
    group level col1 col2 
0  1  10 19 21 
1  1  10 18 24 
2  1  11 14 23 
3  2  5 14 26 
4  2  5 10 22 
5  3  9 13 27 
6  3  9 16 20 
7  3  9 18 26 
8  3  8 11 2 

def get_first_val_keep_cols(group): 
    has_multiple_vals = len(group['level'].unique()) >= 2 
    if has_multiple_vals: 
     return group.loc[group['level'].first_valid_index(), :] 
    else: 
     return None 

df.groupby('group').apply(get_first_val_keep_cols).dropna() 
Out[20]: 
     group level col1 col2 
group       
1   1  10 19 21 
3   3  9 13 27 
+0

如何確保維護其他列,假設原始數據幀具有col1,col2,col3,我仍然希望將其保留爲結果的一部分? –

+0

@BaronYugovich:不是一個巨大的變化,請參閱我的編輯。 – Marius

+0

這神祕地不適合我。使用以前的方法,我得到了正確的結果,只錯過了一些列,現在我得到一個空的數據框。也許這裏返回group.loc [group ['level']。first_valid_index(),:] without,? –

1

這將是簡單的:

In [121]: 

print df.groupby('group').\ 
      agg(lambda x: x.values[0] if (x.values!=x.values[0]).any() else np.nan).\ 
      dropna() 

     level 
group  
1   10 
3   9 

對於每個組,如果任何一個值,與第一個價值不同,將該組合爲其第一個價值;否則,將其彙總到nan

最後,dropna()