2017-08-02 139 views
1
列子值

我的熊貓數據框看起來是這樣的:排序由熊貓

--------------------------------------- 
Name | Stats      
--------------------------------------- 
Bob | { age : 42, profession: IT } 
Jill | { age : 35, profession: Engineer } 
Patric | { age : 37, profession: Student } 
--------------------------------------- 

Stats是一類和ageprofession是這個類的兩個屬性。

我想通過Stats上的一個屬性對該表進行排序。例如,排序它通過人的年齡使表看起來像:

--------------------------------------- 
Name | Stats      
--------------------------------------- 
Jill | { age : 35, profession: Engineer } 
Patric | { age : 37, profession: Student } 
Bob | { age : 42, profession: IT } 
--------------------------------------- 

有沒有辦法做到這一點有熊貓嗎?我只找到了由整列

感謝

回答

2

解決方案
您可以使用argsort找到合適的排序並傳遞到iloc。但是,您需要創建一個數據幀才能在age列上運行argsort

df.iloc[pd.DataFrame(df.Stats.values.tolist()).age.argsort()] 

    Name         Stats 
1 Jill {'age': 35, 'profession': 'Engineer'} 
2 Patric {'age': 37, 'profession': 'Student'} 
0  Bob  {'age': 42, 'profession': 'IT'} 

閱讀@Alexander's answer...後,我想出了結合了他的想法和我的。如果任何人發現這個部分有用,請不要忘記提高他的答案。

df.iloc[np.argsort([x.get('age') for x in df.Stats])] 

定時
小樣本數據

%timeit df.iloc[pd.DataFrame(df.Stats.values.tolist()).age.argsort()] 
%timeit df.iloc[np.argsort([x.get('age') for x in df.Stats])] 
%timeit df.iloc[np.argsort([x.get('age') for x in df.Stats.values.tolist()])] 

1000 loops, best of 3: 756 µs per loop 
1000 loops, best of 3: 225 µs per loop 
1000 loops, best of 3: 207 µs per loop 

設置

df = pd.DataFrame(dict(
    Name='Bob Jill Patric'.split(), 
    Stats=[ 
     dict(age=42, profession='IT'), 
     dict(age=35, profession='Engineer'), 
     dict(age=37, profession='Student') 
    ] 
)) 
+0

謝謝。我很好奇,是什麼讓你覺得嘗試df.Stats.values.tolist()?如果有的話,我會期望增加開銷,而不是減少它 –

+1

@ZainRizvi這個東西的經驗是什麼讓我想到它。如果我想使用列表理解,它可以更快地遍歷列表,而不是通過熊貓系列或numpy數組。 [**請參閱此問題**](https://stackoverflow.com/q/40593444/2336654) – piRSquared

2

使用數據框的一個主要的一點是要鍵入列有效的存儲和計算速度排序(如的Int64,float64,對象等)。你的數據結構不好;您應該爲Stats中的每個字段都有一個單獨的列。有關更多信息,請參見Tidy Data

df2 = df[['Name']].assign(age=[d.get('age') for d in df['Stats']], 
          profession=[d.get('profession') for d in df['Stats']]) 

然後很容易處理您的數據。

>>> df2.sort_values('age') 
    Name age profession 
1 Jill 35 Engineer 
2 Patric 37 Student 
0  Bob 42   IT 
+0

好的技術和好的建議。 – piRSquared