2017-02-18 109 views
1

我想要groupby df [「A」]並且導出df [「B」]中與df [「C」中前兩個最小值相對應的值]pandas groupby排序得到前兩個最小值的行

df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 
        'foo', 'bar', 'foo', 'foo'], 
        'B': ['cat', 'dog', 'rat', 'lion', 
        'bat', 'racoon', 'possum', 'deer'], 
        'C': [1, 2, 6, 4, 3, 1, 2, 4]}) 

我想要得到的結果是:

A B_1  B_2 
0 foo cat  possum 
1 bar racoon dog 
+0

當你試圖做了什麼事? – iled

+0

不知道如何去過去df.groupby(「A」) –

+0

輸出是否正確?請檢查一下。 – jezrael

回答

2

我想你需要:

df1 = df.set_index('B') 
     .groupby('A', sort=False)['C'] 
     .apply(lambda x: pd.Series(x.nsmallest(2).index)) 
     .unstack() 
df1.columns = df1.columns + 1 
df1 = df1.add_prefix('B_').reset_index() 
print (df1) 
    A  B_1  B_2 
0 foo  cat possum 
1 bar racoon  dog 

一行的解決方案:

df1 = df.set_index('B') 
     .groupby('A', sort=False)['C'] 
     .apply(lambda x: pd.Series(x.nsmallest(2).index, index =['B_1','B_2'])) 
     .unstack() 
     .reset_index() 
print (df1) 
    A  B_1  B_2 
0 foo  cat possum 
1 bar racoon  dog 

編輯:

它與datetime完美得:

np.random.seed(100) 
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 
        'foo', 'bar', 'foo', 'foo'], 
        'B': ['cat', 'dog', 'rat', 'lion', 
        'bat', 'racoon', 'possum', 'deer'], 
        'C': np.random.choice(pd.date_range('2017-02-18', 
                 periods=8), 
             size=8, replace=False)}) 
print (df) 
    A  B   C 
0 foo  cat 2017-02-19 
1 bar  dog 2017-02-22 
2 foo  rat 2017-02-23 
3 bar lion 2017-02-20 
4 foo  bat 2017-02-24 
5 bar racoon 2017-02-21 
6 foo possum 2017-02-25 
7 foo deer 2017-02-18 

print (df.dtypes) 
A   object 
B   object 
C datetime64[ns] 

df1 = df.set_index('B') 
     .groupby('A', sort=False)['C'] 
     .apply(lambda x: pd.Series(x.nsmallest(2).index, index =['B_1','B_2'])) 
     .unstack() 
     .reset_index() 
print (df1) 
    A B_1  B_2 
0 foo deer  cat 
1 bar lion racoon 
+0

感謝您的回答。它完美的作品。如果列「C」是日期時間對象,如何使用最小值? –

+0

我必須測試它,給我一點時間。但想法是將datetime轉換爲unix時間,然後它可以完美工作。 – jezrael

+0

我懂了!非常感謝。 –