2016-03-08 30 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