【Python数据分析之pandas03】数据结构的基本功能--2

算数运算和数据对齐

    pandas一个强大的功能是,它可以对不同索引的对象进行算数运算。

s1 = pd.Series([1,2,3,4],index=['a','b','c','d'])
s1
'''
a    1
b    2
c    3
d    4
dtype: int64

'''

s2 = pd.Series([4,78,32,89,61],index=['a','b','e','d','g'])
s2
'''
a     4
b    78
e    32
d    89
g    61
dtype: int64

'''

#将两个Series相加
s1+s2
'''
a     5.0
b    80.0
c     NaN
d    93.0
e     NaN
g     NaN
dtype: float64

'''

    可以看到,对于两个对象相同的索引,值直接想加;对于不同的索引,引入了NaN值。

    而对于DataFrame,只有当行索引和列索引都相同时,才会执行算数操作,否则引入NaN值。

data1 = pd.DataFrame(np.arange(9).reshape((3,3)),columns = list('bcd'),index = ['one','two','three'])
print("data1:")
print(data1)
print('\n')
data2 = pd.DataFrame(np.arange(12).reshape((4,3)),columns = list('bed'),index = ['one','second','three','four'])
print("data2:")
print(data2)
print('\n')
#相加
print("data1+data2:")
print(data1+data2)

'''
结果:
data1:
       b  c  d
one    0  1  2
two    3  4  5
three  6  7  8


data2:
        b   e   d
one     0   1   2
second  3   4   5
three   6   7   8
four    9  10  11


data1+data2:
           b   c     d   e
four     NaN NaN   NaN NaN
one      0.0 NaN   4.0 NaN
second   NaN NaN   NaN NaN
three   12.0 NaN  16.0 NaN
two      NaN NaN   NaN NaN
'''

    但是往往我们希望能够出现数值而非NaN,这时有以下两种方法:

#采用add方法
data1 = pd.DataFrame(np.arange(9).reshape((3,3)),columns = list('bcd'),index = ['one','two','three'])
data2 = pd.DataFrame(np.arange(12).reshape((4,3)),columns = list('bed'),index = ['one','second','three','four'])
print(data1.add(data2,fill_value=0))
'''
结果:
           b    c     d     e
four     9.0  NaN  11.0  10.0
one      0.0  1.0   4.0   1.0
second   3.0  NaN   5.0   4.0
three   12.0  7.0  16.0   7.0
two      3.0  4.0   5.0   NaN
'''

    显然地,这个结果没有达到预期。原因是data1和data2两个对象中,都有对方没有的索引。换句话说,它们之间没有包含关系。而add方法又是单向操作(姑且这么描述吧),没有办法通过add方法对这两个对象的索引进行全覆盖。

data1 = pd.DataFrame(np.arange(9).reshape((3,3)),columns = list('bcd'),index = ['one','two','three'])
data2 = pd.DataFrame(np.arange(12).reshape((4,3)),columns = list('bed'),index = ['one','two','three','four'])
print(data2.reindex(columns = data1.columns,fill_value=0))
'''
       b  c   d
one    0  0   2
two    3  0   5
three  6  0   8
four   9  0  11

'''

    通过重新索引可以对不同索引进行填充,但因为是单向操作,所以有些索引会丢失。

Series和DataFrame之间的运算

    基本上,它们之间的运算会根据Series的索引匹配到DataFrame的列,并且沿着行一直向下广播,若存在不同索引,将会采用并集索引。

import pandas as pd
import numpy as np
data = pd.DataFrame(np.arange(16).reshape(4,4),
                index=['one','two','three','four'],
                columns=['first','second','third','forth'])
series = data.ix[0]
series
'''
first     0
second    1
third     2
forth     3
Name: one, dtype: int32
'''

data-series

结果如下:


    *这里碰到一个之前没有注意的问题:DataFrame中直接索引访问的是列元素,访问行元素要用.ix元素(这里碰到报错,具体原因未知)

排序和排名

    一般使用sort_index方法进行索引排序。

obj =pd. Series(range(4),index=['d','b','a','c'])
obj.sort_index()
'''
a    2
b    1
c    3
d    0
dtype: int64

'''

    如果想要对值进行排序,则采用order方法:

        *这里尝试的时候遇到一个问题,报错总是提示Series没有order属性,实在是苦恼.....

    DataFrame方法同理,可以根据行索引(axis=0),也可通过列索引(axis=1)进行排序

    上述默认排序为升序,可以采用降序,引入其ascending值(默认值为true,即升序)。

frame = pd.DataFrame(np.arange(8).reshape(2,4),index=['three','one'],columns=['d','a','b','c'])
frame
'''
d	a	b	c
three	0	1	2	3
one	4	5	6	7
'''

frame.sort_index(axis=1,ascending=False)

    结果为:


    Data Frame按一个或多个值排序引入by属性:

frame = pd.DataFrame({'b':[1,2,4,3],'c':[24,56,95,3]})
print(frame)
print("引入by属性:")
print(frame.sort_index(by='b'))

'''
b   c
0  1  24
1  2  56
2  4  95
3  3   3
引入by属性:
   b   c
0  1  24
1  2  56
3  3   3
2  4  95
'''

    Series和DataFrame的排名返回了一个Series或DataFrame,其中主要属性是method(破坏平级关系)。默认的method属性是取均值(对值相同的元素取排名均值):

a = pd.Series([3,5,2,7,3,4,9])
a.rank()

'''
0    2.5
1    5.0
2    1.0
3    6.0
4    2.5
5    4.0
6    7.0
dtype: float64
'''

    也可以依照出现顺序排名,不取均值:

a = pd.Series([3,5,2,7,3,4,9])
a.rank(method='first')

'''
0    2.0
1    5.0
2    1.0
3    6.0
4    3.0
5    4.0
6    7.0
dtype: float64
'''

    可以按照较大排名值排名:

a = pd.Series([3,5,2,7,3,4,9])
a.rank(method='max')

'''
0    3.0
1    5.0
2    1.0
3    6.0
4    3.0
5    4.0
6    7.0
dtype: float64
'''

    按较小值排名用法相同,只要把max改成min就可以。

带有重复值的索引

    python允许索引值相同,只是在选取时会将所有拥有这个索引的元素调用出来。

a = pd.Series([1,2,3,4],index=['a','b','a','d'])
a['a']

'''
a    1
a    3
dtype: int64
'''

    


    





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章