2016-03-08 99 views
1

這是我的問題。
我有一個數據幀df其中包含兩列名爲日期wd
表示範圍從(0〜360)的風向。
因此,df表示在某個時間範圍內某處的風向。將風向分爲幾類

我想那些風向分爲16類像這樣:
http://7xrn7f.com1.z0.glb.clouddn.com/16-3-8/30080798.jpg

的範圍這裏介紹。

http://7xrn7f.com1.z0.glb.clouddn.com/16-3-8/8398960.jpg

這是我能對付現在:

wd_stat = [] 
for i in range(0,len(df),1): 
    wd = df.wd.iloc[i] 
    ### NNE 11.25-33.75 
    if 11.25 <= wd < 33.75: 
     wd_stat.append("NNE")  
    ### NE 33.75-56.25 
    if (33.75 <=wd < 56.25): 
     wd_stat.append("NE") 
    ### ENE 56.25 - 78.75  
    if (56.25 <=wd < 78.75): 
     wd_stat.append("ENE") 
    if (78.75 <=wd < 101.25): 
     wd_stat.append("E") 
    if (101.25 <=wd < 123.75): 
     wd_stat.append("ESE") 
     .....not done yet...... 

我的方法不夠靈活和傾倒。
任何人都可以提供一些建議,以高效率處理這樣的分類問題(數字範圍到某些字符)。

回答

5

一個很好的方式做這類事情是使用numpy.digitize()。它需要一系列的bin和值,並返回每個值落入哪個bin的索引。在匹配的字符串數組中使用這些索引可以得到你想要的結果:

import numpy as np 
import pandas as pd 

df = pd.DataFrame({"wd": pd.Series([20.1,50,8.4,359,243,123])}) 

directions = np.array('N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N'.split()) 
bins = np.arange(11.25, 372, 22.5) 
df['wd_stat'] = directions[np.digitize(df['wd'], bins)] 
print df 

     wd wd_stat 
0 20.1  NNE 
1 50.0  NE 
2 8.4  N 
3 359.0  N 
4 243.0  WSW 
5 123.0  ESE 
+1

它確實是非常優雅的解決方案! – MaxU

+0

太麻煩了!謝謝! –

+0

另一個問題在這裏。在你的方法中,[0〜11.25]範圍被替換爲[360〜371.25]。所以我想知道在數字化之前在這些列中添加360。使用'df.iloc [df.loc [0 <= df ['wd'] <11.25] .index] [「wd」] + 360'無法實現。如何基於某些分類將特定行添加到常量? –

2

您可以使用loc

import pandas as pd 

df = pd.DataFrame({"wd": pd.Series([20.1,50,8.4 ])}) 
print df 
    wd 
0 20.1 
1 50.0 
2 8.4 

print (df.wd >= 11.25) & (df.wd < 33.75) 
0  True 
1 False 
2 False 
Name: wd, dtype: bool 

df.loc[(df.wd >= 11.25) & (df.wd < 33.75), 'new'] = 'NNE' 
df.loc[(df.wd >= 33.75) & (df.wd < 56.25), 'new'] = 'NE' 
print df 
    wd new 
0 20.1 NNE 
1 50.0 NE 
2 8.4 NaN