2017-10-11 89 views
2

我有以下的大熊貓據幀在大熊貓,如何根據

+---------+-------+ 
| Country | value | 
+---------+-------+ 
| UK  | 42 | 
| US  |  9 | 
| US  | 10 | 
| France | 15 | 
| France | 16 | 
| Germany | 17 | 
| Germany | 18 | 
| Germany | 20 | 
+---------+-------+ 

我想創造的是,根據每個國家的排名新列的另一列的平均值有秩創建新列他們的價值觀,從最大到最小

平均輸出將類似於以下

+---------+-------+---------+------+ 
| Country | value | Average | Rank | 
+---------+-------+---------+------+ 
| UK  | 42 |  42 | 1 | 
| US  |  9 |  9.5 | 4 | 
| US  | 10 |  9.5 | 4 | 
| France | 15 | 15.5 | 3 | 
| France | 16 | 15.5 | 3 | 
| Germany | 17 |  18 | 2 | 
| Germany | 18 |  18 | 2 | 
| Germany | 20 |  18 | 2 | 
+---------+-------+---------+------+ 

注意,我不需要平均列,它只是在那裏幫助解釋。

非常感謝

回答

5

使用groupby + transformmean,然後rank

df['Average'] = df.groupby('Country')['value'].transform('mean') 
df['Rank'] = df['Average'].rank(method='dense', ascending=False) 
print (df) 
    Country value Average Rank 
0  UK  42 42.000000 1.0 
1  US  9 9.500000 4.0 
2  US  10 9.500000 4.0 
3 France  15 15.500000 3.0 
4 France  16 15.500000 3.0 
5 Germany  17 18.333333 2.0 
6 Germany  18 18.333333 2.0 
7 Germany  20 18.333333 2.0 

類似的解決方案:

a = df.groupby('Country')['value'].transform('mean') 
b = a.rank(method='dense', ascending=False) 

df = df.assign(Average=a, Rank=b) 
print (df) 
    Country value Average Rank 
0  UK  42 42.000000 1.0 
1  US  9 9.500000 4.0 
2  US  10 9.500000 4.0 
3 France  15 15.500000 3.0 
4 France  16 15.500000 3.0 
5 Germany  17 18.333333 2.0 
6 Germany  18 18.333333 2.0 
7 Germany  20 18.333333 2.0 
+0

超清晰和冷凝。雖然應用了相同的方法,但沒有看到類似解決方案的要點。也許你的看法不同+1 –

+0

@AntonvBR - 非常感謝! – jezrael

1

解決方案
我用的pd.DataFrame.joinpd.concat組合爲groupbymean

m = df.groupby('Country').value.mean() 
df.join(
    pd.concat([m, m.rank(ascending=False)], axis=1, keys=['Average', 'Rank']), 
    on='Country') 

    Country value Average Rank 
0  UK  42 42.000000 1.0 
1  US  9 9.500000 4.0 
2  US  10 9.500000 4.0 
3 France  15 15.500000 3.0 
4 France  16 15.500000 3.0 
5 Germany  17 18.333333 2.0 
6 Germany  18 18.333333 2.0 
7 Germany  20 18.333333 2.0 

同樣後,用雙join

m = df.groupby('Country').value.mean() 
df.join(m.rename('Avergage'), on='Country') \ 
    .join(m.rank(ascending=False).rename('Rank'), on='Country') 

    Country value Average Rank 
0  UK  42 42.000000 1.0 
1  US  9 9.500000 4.0 
2  US  10 9.500000 4.0 
3 France  15 15.500000 3.0 
4 France  16 15.500000 3.0 
5 Germany  17 18.333333 2.0 
6 Germany  18 18.333333 2.0 
7 Germany  20 18.333333 2.0 

或用mapassign

m = df.groupby('Country').value.mean() 
df.assign(
    Average=df.Country.map(m), 
    Rank=df.Country.map(m.rank(ascending=False)) 
) 

    Country value Average Rank 
0  UK  42 42.000000 1.0 
1  US  9 9.500000 4.0 
2  US  10 9.500000 4.0 
3 France  15 15.500000 3.0 
4 France  16 15.500000 3.0 
5 Germany  17 18.333333 2.0 
6 Germany  18 18.333333 2.0 
7 Germany  20 18.333333 2.0 
1

我會使用現代化的鏈式方法調用的方法,以避免突變狀態,並創造新的變量:

df = pd.DataFrame(
    {'Country': ['Russia', 'Russia', 'USA'], 'Value': [12, 15, 16]}) 

df.join(df.groupby('Country'). 
      mean(). 
      rank(). 
      rename(columns={'Value': 'Rank'}), 
     on='Country') 
+0

有趣但沒有與兩個具有相同價值的國家合作。 –

+0

你能提供一個例子嗎?我嘗試了'{'國家':['俄羅斯','美國'],'價值':[15,15]}'它給出了等級:[1.5,1.5]'這似乎是一個正確的答案。 –

+0

Nvm,通過等級(method =「dense」)解決了我所看到的「問題」。 (+1) –