美文网首页刺猬教你量化投资
刺猬教你量化投资(七):数据处理进阶

刺猬教你量化投资(七):数据处理进阶

作者: 刺猬偷腥 | 来源:发表于2017-10-13 10:02 被阅读85次
透视数据表可同时求多个函数

index也可以有多个,按顺序进行分组计数:

print df
print "*"*30
df.pivot_table(index=['cat','num'],aggfunc=[np.mean,len],values=['num','cat label']) 
#len表示计数
#以cat列为索引,然后再以num为索引,对每一行的数据先求均值再求长度
​

     num  values         cat  cat label
0    one       2  little cat         20
1    two       3     fat cat         38
2  three       2  little cat         27
3    one       5      my cat         56

Out[8]:

按部就班地求

两个索引同时看有点不好看,那么可以同时制定索引和列名,换种方式呈现结果:

In[9]:
print df
print "*"*30
df.pivot_table(index=['cat'],columns=['num'],aggfunc=[np.mean],values=['num','cat label']) 
#len表示计数
#以cat列为索引,以num的values为打横的列名,然后计算相对应的mean值
#若没结果,则填入空值
​
     num  values         cat  cat label
0    one       2  little cat         20
1    two       3     fat cat         38
2  three       2  little cat         27
3    one       5      my cat         56
******************************
表格变简单了

若需对空值进行填充,则可加上fill_value参数,比如

df.pivot_table(index=['cat'],columns=['num'],aggfunc=[np.mean],values=['num','cat label'],fill_value='0') 
#将空值替换成数字0
大功告成

再进一步,求每列数值占当列数值总额的百分比:

In [10]:
print df1
df1.apply(lambda x:(x/x.sum())*100) #默认按列求和
#如果要按行相处,则加入axis=1即可
#df1.apply(lambda x:(x/x.sum())*100,axis='columns') 
#计算每个值占当列的百分比
             mean                              
           values           cat label          
num           one three two       one three two
cat                                            
fat cat         0     0   3         0     0  38
little cat      2     2   0        20    27   0
my cat          5     0   0        56     0   0

Out[10]:
计算结果

若要在df下面新增一行来显示结果,则可以用df.loc['your cat']=来实现:

In [11]:
print df1
df1.loc['sum']=df1.apply(lambda x:x.sum()) #新增一行显示计算结果
df1
       values  cat label
num                     
one         2         20
two         3         38
three       2         27
one         5         56
Out[11]:
    values  cat label
num     
one     2   20
two     3   38
three   2   27
one     5   56
sum     12  141
  1. index的相关处理

set_index()后,如果想返回初始的状态,则可用reset_index(),如果本身就是初始状态,用了reset_index()后,会多了一个index_0作为列。

若是set_index后,不想显示index的名字而导致多了一个空白行,则可用'df.index.name=None'来使其消失。

还可以用reindex()函数,对数据集的索引进行重新编制,用其他数据集的索引,用原数据集的数据,一一配对,没有数据的地方以空值填充:

In [12]:
df_index=pd.date_range('10/10/2017',periods=5,freq='D')
df1=pd.DataFrame({'cash':[100,30,np.nan,32,199]},index=df_index)
print df1
df_index1=pd.date_range('10/10/2017',periods=8,freq='2D')
df1.reindex(df_index1)
            cash
2017-10-10   100
2017-10-11    30
2017-10-12   NaN
2017-10-13    32
2017-10-14   199
Out[12]:
            cash
2017-10-10  100
2017-10-12  NaN
2017-10-14  199
2017-10-16  NaN
2017-10-18  NaN
2017-10-20  NaN
2017-10-22  NaN
2017-10-24  NaN
  1. 设定数据集的布局

先创建一个df:

In [13]:
df=pd.DataFrame(np.arange(0,12).reshape((3,4)),index=['1','2','3'],columns=['a','b','c','d'])
print df
df1=pd.melt(df,id_vars=['b']) #对df数据集按变量b重新布局,显示出当变量b为某个值时,其他变量对应的values是什么
#改变布局后,只显示两列数据
df1
   a  b   c   d
1  0  1   2   3
2  4  5   6   7
3  8  9  10  11

Out[13]:
重新布局后的结果

实际运用中,可设id_vars=交易日期,然后就得出两列数据,股票代码和收盘价。

In [14]:
df1=pd.melt(df,id_vars=['b'],value_vars=['c'])
df1
Out[14]:
    b   variable    value
0   1   c   2
1   5   c   6
2   9   c   10

变回去也行,用pivot_table()即可:

In [14]:
df1=pd.melt(df,id_vars=['a'])
print df1
df1.pivot_table(index='a',columns='variable',values='value')  #pivot_table是melt的反面
​
   a variable  value
0  0        b      1
1  4        b      5
2  8        b      9
3  0        c      2
4  4        c      6
5  8        c     10
6  0        d      3
7  4        d      7
8  8        d     11
Out[14]:
variable    b   c   d
a           
0   1   2   3
4   5   6   7
8   9   10  11

要把这个a消掉,加个reset_index()即可。

  1. 类别设置

以学生考试成绩打分为例,将不同分值的结果赋予定性的判断:

In [15]:
import pandas as pd
import numpy as np
df=pd.DataFrame({'student':['one','two','three','four'],'marks':[55,79,73,62],'raw_grade':['c','a','a','b']})
df['grade']=df['raw_grade'].astype('category') #新增一列,内容是marks的values,但类别为分类
df.set_index('student')
print df['grade']
df['grade'].cat.categories=['good','just so so','bad'] #分别对应a\b\c, cat是category的意思
df['grade']
​
0    c
1    a
2    a
3    b
Name: grade, dtype: category
Categories (3, object): [a, b, c]
Out[15]:
0           bad
1          good
2          good
3    just so so
Name: grade, dtype: category
Categories (3, object): [good, just so so, bad]
  1. 链接两个df

假如有两个df表,他们某个列有相同的values,则可以进行合并,进行对应填充:

In [16]:
import pandas as pd
import numpy as np
df1=pd.DataFrame({'animal':['dog','cat','cat','cow','dog'],'price':[55,79,73,62,40],'grade':['c','a','c','b','d']})
df2=pd.DataFrame({'animals':['dog','cat','cow'],'weight':[553,792,731]})
print df1
print df2
df=pd.merge(df1,df2,how='inner',left_on='animal',right_on='animals') #方式用内部合并,左边显示animal的数据,右边显示animals的数据,对应填充。
df
  animal grade  price
0    dog     c     55
1    cat     a     79
2    cat     c     73
3    cow     b     62
4    dog     d     40
  animals  weight
0     dog     553
1     cat     792
2     cow     731

Out[16]:
df合并后的结果

还有另外一种方法,就是将index设为一致,然后再合并,比如:

In [17]:
import pandas as pd
import numpy as np
df1=pd.DataFrame({'animal':['dog','cat','cat','cow','dog'],'price':[55,79,73,62,40],'grade':['c','a','c','b','d']})
df2=pd.DataFrame({'animals':['dog','cat','cow'],'weight':[553,792,731]})
print '*'*30
print df1
print '*'*30
print df2
print '*'*30
one=df1.set_index('animal')
two=df2.set_index('animals')
print one
print '*'*30
print two
print '*'*30
print two.reindex(one.index)
print '*'*30
one['weight']=two.reindex(one.index)  #新增一列的内容就是tworeindex后的value,填充过去了
print one
******************************
  animal grade  price
0    dog     c     55
1    cat     a     79
2    cat     c     73
3    cow     b     62
4    dog     d     40
******************************
  animals  weight
0     dog     553
1     cat     792
2     cow     731
******************************
       grade  price
animal             
dog        c     55
cat        a     79
cat        c     73
cow        b     62
dog        d     40
******************************
         weight
animals        
dog         553
cat         792
cow         731
******************************
        weight
animal        
dog        553
cat        792
cat        792
cow        731
dog        553
******************************
       grade  price  weight
animal                     
dog        c     55     553
cat        a     79     792
cat        c     73     792
cow        b     62     731
dog        d     40     553
  1. isnull()的补充

前面提到如何使用isnull()函数去判断数据表中是否有空值:

In[18]:
print df
print df.isnull()*1
print np.sum(df.isnull()*1,axis=0) #axis=0意味着按列相加,axis=1意味着按行相加
np.sum(df.isnull()*1,axis=1) !=0
   one  two  three
a    1    1      2
b    2    2      4
c    3    3      6
d  NaN    4    NaN
   one  two  three
a    0    0      0
b    0    0      0
c    0    0      0
d    1    0      1
one      1
two      0
three    1
dtype: int64
Out[18]:
a    False
b    False
c    False
d     True
dtype: bool

加上any参数,如isnull().any(axis=1),即可判断每一行是否有空值,返回布尔值。不定义axis,则默认按列检查。

9.改变数据类型

astype()可以改变数据类型,对于数据表中的某行某列,可以改变类型后再赋予自己,比如:df['a','b']=df['a','b'].astype(float)

结语

至此,我们已掌握了Python的基本知识。下一章我们将学习金融建模中的excel函数,敬请期待。


刺猬偷腥
2017年10月13日


to be continued.

相关文章

网友评论

    本文标题:刺猬教你量化投资(七):数据处理进阶

    本文链接:https://www.haomeiwen.com/subject/abfoyxtx.html