再探Pandas的使用

Pandas的简单使用

看过Pandas简单使用的同学,可能会觉得那是相当的意犹未尽,想要看一看Pandas更深入的使用方法?那就试试这一篇把!

转载请注明出处

apply的使用

我喜欢二话不说,先甩代码:

import pandas as pd
import numpy as np
import matplotlib 
from matplotlib import pyplot

dates = pd.date_range('20150201', periods=6)
np.random.seed(0)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))

#这里还是使用上篇博客的数据结构,并且使用了喜闻乐见的固定随机seed来保证数据可复现
print(df.apply(lambda x:x+1)) #发现新东西了,可以见得,这个apply就是将一个函数应用在每个数据上

output:
                   A         B         d         D
2015-02-01  2.764052  1.400157  1.978738  3.240893
2015-02-02  2.867558  0.022722  1.950088  0.848643
2015-02-03  0.896781  1.410599  1.144044  2.454274
2015-02-04  1.761038  1.121675  1.443863  1.333674
2015-02-05  2.494079  0.794842  1.313068  0.145904
2015-02-06 -1.552990  1.653619  1.864436  0.257835

这里为每个数据都执行了+1操作。
这里本身并不难,但是有两点可以注意一下:
1、apply的时候,一次应用一个列,也就是说lambda中取出的x就依次是(A,B,C,D)这四列,而不是一个一个的数
2、apply返回一个修改后的DataFrame结构,但并不修改原数据
有了这些知识,我们就可以发挥无穷的想象力了,比如说,为一列数据求一下均值、求一下方差、将数据映射到0~1的区间,等等。

数据的统计操作:

s = pd.Series(np.random.randint(0, 7, size=10))
print(s)
print(s.value_counts()) #统计数据出现频率

0    4
1    1
2    2
3    4
4    3
5    4
6    6
7    4
8    4
9    3
dtype: int32
4    5
3    2
6    1
2    1
1    1
dtype: int64

我们可以对数据进行一些统计,频率、中位数、方差等等
更多信息,可以移步这里

数据的一些聚合操作

piece = [df[0:3],df[3:]]
print(piece[0],'\n',piece[1])
print(pd.concat(piece))

output:
                   A         B         d         D
2015-02-01  1.764052  0.400157  0.978738  2.240893
2015-02-02  1.867558 -0.977278  0.950088 -0.151357
2015-02-03 -0.103219  0.410599  0.144044  1.454274 
                    A         B         d         D
2015-02-04  0.761038  0.121675  0.443863  0.333674
2015-02-05  1.494079 -0.205158  0.313068 -0.854096
2015-02-06 -2.552990  0.653619  0.864436 -0.742165
                   A         B         d         D
2015-02-01  1.764052  0.400157  0.978738  2.240893
2015-02-02  1.867558 -0.977278  0.950088 -0.151357
2015-02-03 -0.103219  0.410599  0.144044  1.454274
2015-02-04  0.761038  0.121675  0.443863  0.333674
2015-02-05  1.494079 -0.205158  0.313068 -0.854096
2015-02-06 -2.552990  0.653619  0.864436 -0.742165

concat是数据的拼接。可以看到,本来被分开的两个数据,被重新拼接了。
concat有axis参数,0代表按行拼接,1代表按列拼接

表的join和group

既然是表,那么就应该支持join和group,DataFrame显然是准备这样做的,它的join和group和mysql语句的思想是类似的。
下面请听一道小学应用题:
如果sam有2只猫分别叫做一号和二号猫,和两只狗,分别叫做一号和二号狗
同时,jack有两只猫分别叫做一号和二号猫,和一只狗,叫做一号狗,
请问,如果他们出门的时候各自溜自己的一只狗和一条猫,那么有多少种溜法?
这在数据库就是一种join操作了,解答如下(当然是代码了):

p1 = pd.DataFrame({'owner':['sam','sam','jack'],'dog':['No.1','No.2','No.1']})
p2 = pd.DataFrame({'owner':['jack','jack','sam','sam'],'cat':['No.1','No.2','No.1','No.2']})
print(pd.merge(p1, p2,on='owner'))

output:
  owner   dog   cat
0   sam  No.1  No.1
1   sam  No.1  No.2
2   sam  No.2  No.1
3   sam  No.2  No.2
4  jack  No.1  No.2
5  jack  No.1  No.1

可以看到,sam有4种溜法,jack有2种溜法,总共就有8种溜法
这里merge就是一种join操作,根据某一行,对数据进行排列组合,这里是根据owner行进行的。

好,既然解题解得很开心,那么再来一题:
幼儿园应用题:
sam有三个藏零钱的地方,每个地方藏了1,2,3块钱
jack有两个藏零钱的地方,每个地方藏了1,3块钱,
请问,他们一共有多少零钱?
解答如下:

p1 = pd.DataFrame({'money':[1,2,3],'owner':['sam','sam','sam']})
p2 = pd.DataFrame({'money':[1,3],'owner':['jack','jack']})
print(p1)
print(p2)
p12 = pd.concat([p1,p2])
print(p12.groupby('owner').sum())

output:
   money owner
0      1   sam
1      2   sam
2      3   sam
   money owner
0      1  jack
1      3  jack
       money
owner       
jack       4
sam        6

可以看到,groupby操作对一组数据进行了操作,这里进行的是求和操作,最终果然求出了二者的零花钱数目。

数据的reshape处理

在进行数据分析的时候,经常要reshape,现在,我们就来看看再pandas中,这些操作是如何进行的

首先,我们创建一个新的数据结构

tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
                     'foo', 'foo', 'qux', 'qux'],
                   ['one', 'two', 'one', 'two',
                     'one', 'two', 'one', 'two']]))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df2 = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
print(df2)

output:
                     A         B
first second                    
bar   one     0.259735 -1.681349
      two    -0.916795 -0.119224
baz   one    -0.446277 -2.143355
      two     0.010038 -0.558223
foo   one     0.480906 -0.574142
      two    -0.252468  1.039847
qux   one    -0.023480  0.089422
      two    -0.594327 -0.105697

可以见得,这个数据结构是有两层index的,并且每层index有自己的命名。

先进行一下stack操作看看结果:

stacked = df2.stack()
print(stacked)

output:
first  second   
bar    one     A   -1.733742
               B   -0.615564
       two     A   -0.954634
               B   -0.248805
baz    one     A   -0.055088
               B    0.282070
       two     A   -1.894318
               B    0.838311
foo    one     A   -0.416312
               B    1.356928
       two     A   -1.197659
               B   -1.677046
qux    one     A    1.011233
               B   -0.728128
       two     A   -0.217235
               B    0.530017
dtype: float64

可以看到,列的维度被stack了,结果很令人满意

继续操作,unstacked一下:

print(stacked.unstack())

output:
                     A         B
first second                    
bar   one    -1.733742 -0.615564
      two    -0.954634 -0.248805
baz   one    -0.055088  0.282070
      two    -1.894318  0.838311
foo   one    -0.416312  1.356928
      two    -1.197659 -1.677046
qux   one     1.011233 -0.728128
      two    -0.217235  0.530017
#一次unstacked 数据回去了

print(stacked.unstack().unstack())

output:
               A                   B          
second       one       two       one       two
first                                         
bar    -1.733742 -0.954634 -0.615564 -0.248805
baz    -0.055088 -1.894318  0.282070  0.838311
foo    -0.416312 -1.197659  1.356928 -1.677046
qux     1.011233 -0.217235 -0.728128  0.530017
#两次unstack,数据按index标签的最后一个展开了

Pivot 变换

数据变换中,轴变换可以说是引人入胜的一种变换,因为它总能给人一些看数据的新角度。下面介绍一下pandas的轴变换

我们先尝试一下对刚才建立的df2进行一下轴变换:

print(pd.pivot_table(df2, values='A', index=['first'], columns=['second']))

output:
second       one       two
first                     
bar    -1.895953 -0.327675
baz     1.005549  1.556680
foo    -0.409717 -0.250979
qux    -0.639086 -3.005128

可以看到这里选择了’first‘这一index作为df2的index而选择了’second‘作为columns,数据上则是仅使用’A’列数据。

Categoricals 设置

DataFrame允许用户对数据进行类型的标注,操作如下:

df3 = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
#新建一个数据结构
df3["grade"] = df3["raw_grade"].astype("category")
print(df3,'\n')
df3["grade"].cat.categories = ["very good", "good", "very bad"]
print(df3)

output:
   id raw_grade grade
0   1         a     a
1   2         b     b
2   3         b     b
3   4         a     a
4   5         a     a
5   6         e     e 

   id raw_grade      grade
0   1         a  very good
1   2         b       good
2   3         b       good
3   4         a  very good
4   5         a  very good
5   6         e   very bad

可以见得,设置种类类别之后,grade这一栏被相应的改变了。
这样提供给我们一个好处就是grade栏是由一定数量的数据类型决定的,而不能被随意修改成任意值。

绘制

辛苦处理了半天数据,是否想要可视化一下?可以得,让我们尝试一下pandas自带的绘制接口

array = [np.sin(i) for i in np.arange(0,2*np.pi+np.pi/20,np.pi/20)]
s = pd.Series(array)
s.plot()

输出如下:
这里写图片描述
一个很正经的正弦图像出现了。

再来试试DataFrame

array1 = [np.sin(i) for i in np.arange(0,2*np.pi+np.pi/20,np.pi/20)]
array2 = [np.cos(i) for i in np.arange(0,2*np.pi+np.pi/20,np.pi/20)]
index1 = [i for i in np.arange(0,2*np.pi+np.pi/20,np.pi/20)]

df4 = pd.DataFrame({'sin':array1,'cos':array2},index=index1)
df4.plot()

这里写图片描述
一个很正经的sin和cosin的图像。
好,尝试成功了!

保存和导入

数据经常需要从各种数据文件中导入导出,怎么办?肯定是有接口的,下面罗列几个

df.to_csv('foo.csv')
pd.read_csv('foo.csv')
df.to_hdf('foo.h5','df')
pd.read_hdf('foo.h5','df')
df.to_excel('foo.xlsx', sheet_name='Sheet1')
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])

这里望文生义,就可以理解用法了。

关于DataFrame的介绍就告一段落了,之后在Tensorflow上会有pandas的应用,到时再在实践中,做进一步讲解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值