2017-03-11 48 views
2

我有形式產生新的熊貓數據幀,通過跨行

data = [{'Energy': 2,'spin': 1},{'Energy': 6,'spin': 2},{'Energy':5,'spin':2}, 
     {'Energy': 15,'spin': 5},{'Energy': 4,'spin': 1}, {'Energy': 10,'spin': 5}] 

df=pd.DataFrame(data, index=['Particle 1', 'Particle 2','Particle 3', 
          'Particle 4','Particle 5','Particle 6']) 
print(df) 

的數據幀對於每個組具有相同的自旋顆粒的子集保持最低,我想繼續只有能量最小的那個,然後放下其餘的。這是,結果數據幀應該看起來像這樣:

dataclean = [{'Energy': 2,'spin': 1},{'Energy': 5,'spin': 2},{'Energy': 10,'spin': 5}] 

df2=pd.DataFrame(dataclean, index=['Particle 1','Particle 3','Particle 6']) 
print(df2) 

      Energy spin 
Particle 1  2  1 
Particle 3  5  2 
Particle 6  10  5 

我試過不同的方法失敗。這樣做的最簡單方法是什麼?

回答

3

您可以使用idxmin()找出指數在能源最小每個,然後用它來子集原始數據幀(這個假設你沒有複製指數):

df.loc[df.groupby("spin").Energy.idxmin()] 

enter image description here


另一種選擇:使用nsmallest

df.groupby('spin').Energy.nsmallest(1).reset_index(level=0) 

enter image description here

+0

釷很多,這很好用!更新:如果我有兩個具有完全相同自旋和完全相同能量的粒子(比如那個自旋的最小值)。例如,假設我有一個「能量= 10」和「自旋= 5」的粒子7(即與「粒子6」相同)。是否有可能在新的數據框中保留「Particle 6」和「Particle 7」? – Jon

+0

在這種情況下,您希望保持相等的最小值,您可以使用'groupby.transform'來計算等長的最小向量並將其用於子集化。 'df [df.Energy == df.groupby('spin')。Energy.transform('min')]' – Psidom

+0

很好用,很感謝! – Jon

0

UPDATE:

來源DF

In [70]: df 
Out[70]: 
      Energy spin 
Particle 1  2  1 
Particle 2  6  2 
Particle 3  5  2 
Particle 4  15  5 
Particle 5  4  1 
Particle 6  10  5 
Particle 7  10  5 # i've added this row 

解決方案中,使用方法GroupBy.rank(method='dense')

In [71]: df.loc[df.groupby('spin').Energy.rank(method='dense').le(1)] 
Out[71]: 
      Energy spin 
Particle 1  2  1 
Particle 3  5  2 
Particle 6  10  5 
Particle 7  10  5 

說明:

In [72]: df.groupby('spin').Energy.rank(method='dense') 
Out[72]: 
Particle 1 1.0 
Particle 2 2.0 
Particle 3 1.0 
Particle 4 2.0 
Particle 5 2.0 
Particle 6 1.0 
Particle 7 1.0 
Name: Energy, dtype: float64 

In [73]: df.groupby('spin').Energy.rank(method='dense').le(1) 
Out[73]: 
Particle 1  True 
Particle 2 False 
Particle 3  True 
Particle 4 False 
Particle 5 False 
Particle 6  True 
Particle 7  True 
Name: Energy, dtype: bool 

OLD答案:

替代解決方案:

In [60]: df.sort_values('Energy').groupby('spin').head(1) 
Out[60]: 
      Energy spin 
Particle 1  2  1 
Particle 3  5  2 
Particle 6  10  5 

PS請注意,@Psidom's solution: df.groupby('spin').Energy.nsmallest(1).reset_index(level=0)是更地道,應該進行更好的

+0

非常感謝!很高興有多種解決方案 – Jon

+0

@Jon,歡迎您。我已經添加了另一個解決方案,它應該照顧重複 – MaxU

+0

好東西,非常感謝您的補充! – Jon