1. 程式人生 > >pandas數據大發888平臺出租規整化:清理、轉換、合並、重塑

pandas數據大發888平臺出租規整化:清理、轉換、合並、重塑

右連接 foo 規整化 float 數據集 str none num out

數據分析和大發888平臺出租 haozbbs.com Q1446595067建模方面的大量編程工作都是用在數據準備上的:加載、清理、轉換以及重塑。
許多人選擇使用通用編程語言或unix文本處理工具(如sed或awk)對數據格式進行專門處理。

幸運的是,pandas和python標準庫提供了一組高級的、靈活的、高效的核心函數和算法,將數據規整化正確的形式。

  1. 合並數據集:

pandas對象中的數據可以通過一些內置的方式進行合並:
(1)pandas.merge可根據一個名多個鍵將不同DataFrame中的行連接起來。sql關系型數據庫也有merge法,它是用merge實現的就是數據庫的連接操作(inner內連接交集,outer外連接,左連接,右連接=>並集)。

(2)pandas.concat可以沿著一條軸將多個對象堆疊到一起。

(3)實例方法combine_first可以將重復數據編接在一起,用一個對象中的值填充另一個對象中的缺失值。

下面分別講解這些方法:

數據庫風格的DataFrame合並:

數據集的合並(merge)或連接(join)運算是通過一個或多個鍵將行連接起來的。這些運算是關系型數據庫的核心。

pandas的merge函數是對數據應用這些算法的主要切入點。

(1)merge的用法

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

df1=DataFrame({‘key‘:[‘b‘,‘b‘,‘a‘,‘c‘,‘a‘,‘a‘,‘b‘],
               ‘data1‘:range(7)})
df2=DataFrame({‘key‘:[‘a‘,‘b‘,‘d‘],
               ‘data2‘:range(3)})
print df1
#輸出結果如下:
#    data1 key
# 0      0   b
# 1      1   b
# 2      2   a
# 3      3   c
# 4      4   a
# 5      5   a
# 6      6   b
# print df2
# #輸出結果如下:
#    data2 key
# 0      0   a
# 1      1   b
# 2      2   d
(1)這是一種多對一的合並:df1中的數據有多個被標記為a和b行,而df2中key列的每個值則僅對應一行。
    這些對象調用merge即可得到
print pd.merge(df1,df2)
#輸出結果如下:
#    data1 key  data2
# 0      0   b      1
# 1      1   b      1
# 2      6   b      1
# 3      2   a      0
# 4      4   a      0
# 5      5   a      0
# #註意:上面的例子並沒有指明要用哪個列進行連接。如果沒有指定,merge就會將重疊列的列名當做鍵。
(2)下面指定列:用能數on=
# print pd.merge(df1,df2,on=‘key‘) #輸出結果與上面一樣

(3)如果兩個對象的列名不同,也可以分別進行指定:left_on,right_on
df3=DataFrame({‘lkey‘:[‘b‘,‘b‘,‘a‘,‘c‘,‘a‘,‘a‘,‘b‘],
               ‘data1‘:range(7)})
df4=DataFrame({‘rkey‘:[‘a‘,‘b‘,‘d‘],
               ‘data2‘:range(3)})
print pd.merge(df3,df4,left_on=‘lkey‘,right_on=‘rkey‘)
#輸出結果如下:
#    data1 lkey  data2 rkey
# 0      0    b      1    b
# 1      1    b      1    b
# 2      6    b      1    b
# 3      2    a      0    a
# 4      4    a      0    a
# 5      5    a      0    a
#
#註意:結果裏面c和d以及與之相關的數據消失了。默認情況下,merge做的是"inner"連接:結果中的鍵是交集。
#     而其它外連接left,right,outer求取的是鍵的並集,組合了左連接和右連接的效果。
(4) outer外連接:並集,兩個數據Key都要
# print pd.merge(df1,df2,how=‘outer‘)  #外連接,兩邊的key都要傳入
# #輸出結果如下:並集,df1,df2所有的值都放入
# #    data1 key  data2
# # 0    0.0   b    1.0
# # 1    1.0   b    1.0
# # 2    6.0   b    1.0
# # 3    2.0   a    0.0
# # 4    4.0   a    0.0
# # 5    5.0   a    0.0
# # 6    3.0   c    NaN
# # 7    NaN   d    2.0

(5) left左連接:並集,左連接是以左邊的為主
# print pd.merge(df1,df2,on=‘key‘,how=‘left‘) #左連接
# #輸出結果如下:  左連接是以左邊的為主,即df1為主,顧只有df1的key
# #    data1 key  data2
# # 0      0   b    1.0
# # 1      1   b    1.0
# # 2      2   a    0.0
# # 3      3   c    NaN
# # 4      4   a    0.0
# # 5      5   a    0.0
# # 6      6   b    1.0

(6)right右連接:並集,右連接是以右邊的為主
# print pd.merge(df1,df2,how=‘right‘)  #右連接
# #輸出結果如下:右連接,以df2的為主,顧只有df2的key,其它的值是全部寫入
# #    data1 key  data2
# # 0    0.0   b      1
# # 1    1.0   b      1
# # 2    6.0   b      1
# # 3    2.0   a      0
# # 4    4.0   a      0
# # 5    5.0   a      0
# # 6    NaN   d      2

(7)inner內連接:交集,默認就是內連接
# print pd.merge(df1,df2,how=‘inner‘) #即merge默認情況下是inner,inner是交集
# #輸出結果如下:取df1,df2都有key
# #    data1 key  data2
# # 0      0   b      1
# # 1      1   b      1
# # 2      6   b      1
# # 3      2   a      0
# # 4      4   a      0
# # 5      5   a      0

(8)若多個鍵要進行合並,傳入一個由列名組成的列表即可
left=DataFrame({‘key1‘:[‘foo‘,‘foo‘,‘bar‘],
                ‘key2‘:[‘one‘,‘two‘,‘one‘],
                ‘lval‘:[1,2,3]})
right=DataFrame({‘key1‘:[‘foo‘,‘foo‘,‘bar‘,‘bar‘],
                 ‘key2‘:[‘one‘,‘one‘,‘one‘,‘two‘],
                 ‘rval‘:[4,5,6,7]})
print left
#輸出結果如下:
#   key1 key2  lval
# 0  foo  one     1
# 1  foo  two     2
# 2  bar  one     3
print right
#輸出結果如下:
#   key1 key2  rval
# 0  foo  one     4
# 1  foo  one     5
# 2  bar  one     6
# 3  bar  two     7
print pd.merge(left,right,on=[‘key1‘,‘key2‘],how=‘outer‘)
#輸出結果如下:看key1,key2兩個鍵對應的lval的值。外連接,即所有的key都要。
#right中的key組合[foo,one],[foo,one],[foo,two]...用right的key看left有沒有。
#   key1 key2  lval  rval
# 0  foo  one   1.0   4.0
# 1  foo  one   1.0   5.0
# 2  foo  two   2.0   NaN
# 3  bar  one   3.0   6.0
# 4  bar  two   NaN   7.0

(9)合並運算需要考慮對重復列名的處理,merge有一個實用的suffixes選項,用於指定附加到左右兩個DataFrame對象的重疊列名上的字符串。
print pd.merge(left,right,on=‘key1‘) #只用單個key,它就有單個key1分別和left,right的key2的組合
#輸出結果如下:
#   key1 key2_x  lval key2_y  rval
# 0  foo    one     1    one     4
# 1  foo    one     1    one     5
# 2  foo    two     2    one     4
# 3  foo    two     2    one     5
# 4  bar    one     3    one     6
# 5  bar    one     3    two     7
print pd.merge(left,right,on=‘key1‘,suffixes=(‘_left‘,‘_right‘))
#輸出結果如下:
#   key1 key2_left  lval key2_right  rval
# 0  foo       one     1        one     4
# 1  foo       one     1        one     5
# 2  foo       two     2        one     4
# 3  foo       two     2        one     5
# 4  bar       one     3        one     6
# 5  bar       one     3        two     7

merger函數的參數
參數 說明
left 參與合並的左側DataFrame
right 參與合並的右側DataFrame
how “inner”、“outer”、“left”、“right”其中之一。默認為"inner"(交集),其它為並集
on 用於連接的列名。必須存在於左右兩個DataFrame對象中。如果未指定,且其它連接鍵也未指定,由以
left和right列名的交集作為連接鍵
left_on 左側DataFrame中用作連接鍵的列
right_on 右側DataFrame中用作連接鍵的列
left_index 將左側的行索引用作其連接鍵
righgt_index 將右側的行索引用作其連接鍵

sort 根據連接鍵對合並後的數據進行排序,默認為True.有時處理大數據集時,禁用該選項可獲得更好的性能
suffixes 字符串值元組,用於追加到重疊列名的末尾,默認為(‘_x‘,‘_y‘).
copy 設置為False,可以在某些特殊情況下避免將數據復制到結果數據結構中。默認總是復制。

索引上DataFrame的合並:

DataFrame中的連接鍵位於其索引中。在這種情況下,可以傳入left_index=True或right_index=True(或兩個都傳)

以說明索引應該被用作連接鍵。

(1)merge的用法:索引上合並用left_index=True、right_index=True

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

(1)DataFrame中的連接鍵位於其索引中:left_index=True或right_index=True(或兩個都傳)來說明索引應該被用作連接鍵。
left1=DataFrame({‘key‘:[‘a‘,‘b‘,‘a‘,‘a‘,‘b‘,‘c‘],
                 ‘value‘:range(6)})
right1=DataFrame({‘group_val‘:[3.5,7]},index=[‘a‘,‘b‘])
print left1
#輸出結果如下:
#   key  value
# 0   a      0
# 1   b      1
# 2   a      2
# 3   a      3
# 4   b      4
# 5   c      5
print right1
#輸出結果如下:
#    group_val
# a        3.5
# b        7.0
print pd.merge(left1,right1,left_on=‘key‘,right_index=True)
#輸出結果如下:
#   key  value  group_val
# 0   a      0        3.5
# 2   a      2        3.5
# 3   a      3        3.5
# 1   b      1        7.0
# 4   b      4        7.0

(2)由於默認的merge方法是求取連接鍵的交集,因此可以通過外連接的方式得到它們的並集。how=‘outer‘
print pd.merge(left1,right1,left_on=‘key‘,right_index=True,how=‘outer‘)
#輸出結果如下:
#   key  value  group_val
# 0   a      0        3.5
# 2   a      2        3.5
# 3   a      3        3.5
# 1   b      1        7.0
# 4   b      4        7.0
# 5   c      5        NaN

(3)層次化索引,多層行/列索引
lefth=DataFrame({‘key1‘:[‘Ohio‘,‘Ohio‘,‘Ohio‘,‘Nevada‘,‘Nevada‘],
                 ‘key2‘:[2000,2001,2002,2001,2002],
                 ‘data‘:np.arange(5.)})
righth=DataFrame(np.arange(12).reshape(6,2),
                 index=[[‘Nevada‘,‘Nevada‘,‘Ohio‘,‘Ohio‘,‘Ohio‘,‘Ohio‘],
                 [2001,2000,2000,2000,2001,2002]],
                 columns=[‘event1‘,‘event2‘])
print lefth
#輸出結果如下:
#    data    key1  key2
# 0   0.0    Ohio  2000
# 1   1.0    Ohio  2001
# 2   2.0    Ohio  2002
# 3   3.0  Nevada  2001
# 4   4.0  Nevada  2002
print righth
#輸出結果如下:
#              event1  event2
# Nevada 2001       0       1
#        2000       2       3
# Ohio   2000       4       5
#        2000       6       7
#        2001       8       9
#        2002      10      11
#必須以列表的形式指明用作合並鍵的多個列(註意對重復索引值的處理)
#left_on左側DataFrame作為連接鍵,即lefth,而索引是right_index,即右側數據為行索引即righth的行索引為行索引
print pd.merge(lefth,righth,left_on=[‘key1‘,‘key2‘],right_index=True)
#沒有how參數,默認是inner連接,即交集,取lefth的[‘key1‘,‘key2‘]的數據與righth的行有交集,即相同的取出
#輸出結果如下:
#    data    key1  key2  event1  event2
# 0   0.0    Ohio  2000       4       5
# 0   0.0    Ohio  2000       6       7
# 1   1.0    Ohio  2001       8       9
# 2   2.0    Ohio  2002      10      11
# 3   3.0  Nevada  2001       0       1

#(4)外連接:how=‘outer‘ 並集
print pd.merge(lefth,righth,left_on=[‘key1‘,‘key2‘],right_index=True,how=‘outer‘)
#輸出結果如下:
#    data    key1  key2  event1  event2
# 0   0.0    Ohio  2000     4.0     5.0
# 0   0.0    Ohio  2000     6.0     7.0
# 1   1.0    Ohio  2001     8.0     9.0
# 2   2.0    Ohio  2002    10.0    11.0
# 3   3.0  Nevada  2001     0.0     1.0
# 4   4.0  Nevada  2002     NaN     NaN
# 4   NaN  Nevada  2000     2.0     3.0

#(5)用merge同時使用合並雙方的索引
left2=DataFrame([[1.,2.],[3.,4.],[5.,6.]],index=[‘a‘,‘c‘,‘e‘],
                columns=[‘Ohio‘,‘Nevada‘])
right2=DataFrame([[7.,8.],[9.,10.],[11.,12.],[13,14]],
                 index=[‘b‘,‘c‘,‘d‘,‘e‘],columns=[‘Missouri‘,‘Alabama‘])
print left2
#輸出結果如下:
#    Ohio  Nevada
# a   1.0     2.0
# c   3.0     4.0
# e   5.0     6.0
print right2
#輸出結果如下:
#    Missouri  Alabama
# b       7.0      8.0
# c       9.0     10.0
# d      11.0     12.0
# e      13.0     14.0
print pd.merge(left2,right2,how=‘outer‘,left_index=True,right_index=True)
#同時使用了left_index,right_index同時合並雙方索引,且outer外連接交集
#輸出結果如下:
#    Ohio  Nevada  Missouri  Alabama
# a   1.0     2.0       NaN      NaN
# b   NaN     NaN       7.0      8.0
# c   3.0     4.0       9.0     10.0
# d   NaN     NaN      11.0     12.0
# e   5.0     6.0      13.0     14.0

(2)join的用法:索引上合並用left_index=True、right_index=True

DataFrame的一個實例方法Join:更為方便地實現按索引合並。它還可以用於合並多個帶有相同或相似索引的DataFrame對象,而不管它們之間有沒有重疊的列。

#Join:在連接鍵上是做左連接
# (1)DataFrame的一個實例方法Join:更為方便地實現按索引合並。不管它們之間有沒有重疊的列。
#上面的例子可以編寫如下:
print left2.join(right2,how=‘outer‘)  #類似python的字符串連接Join
#輸出結果如下:
#    Ohio  Nevada  Missouri  Alabama
# a   1.0     2.0       NaN      NaN
# b   NaN     NaN       7.0      8.0
# c   3.0     4.0       9.0     10.0
# d   NaN     NaN      11.0     12.0
# e   5.0     6.0      13.0     14.0

# (2)它還支持DataFrame的索引跟調用者DataFrame的某個列之間的連接(即第一個DataFrame的行索引與第二個DataFrame的列連接)
print left1.join(right1,on=‘key‘)
#輸出結果如下:
#   key  value  group_val
# 0   a      0        3.5
# 1   b      1        7.0
# 2   a      2        3.5
# 3   a      3        3.5
# 4   b      4        7.0
# 5   c      5        NaN

#(3)可以向join傳入一組DataFrame
another=DataFrame([[7.,8.],[9.,10.],[11.,12.],[16.,17.]],
                 index=[‘a‘,‘c‘,‘e‘,‘f‘],columns=[‘New York‘,‘Oregon‘])
print another
#輸出結果如下:
#    New York  Oregon
# a       7.0     8.0
# c       9.0    10.0
# e      11.0    12.0
# f      16.0    17.0
print left2.join([right2,another]) #left2左分別連接right2,another
# left2內容如下:
# #    Ohio  Nevada
# # a   1.0     2.0
# # c   3.0     4.0
# # e   5.0     6.0
# right2內容如下:
# #    Missouri  Alabama
# # b       7.0      8.0
# # c       9.0     10.0
# # d      11.0     12.0
# # e      13.0     14.0
#left2.join([right2,another])輸出結果如下:
#    Ohio  Nevada  Missouri  Alabama  New York  Oregon
# a   1.0     2.0       NaN      NaN       7.0     8.0
# c   3.0     4.0       9.0     10.0       9.0    10.0
# e   5.0     6.0      13.0     14.0      11.0    12.0

軸上連接:

另一種數據合並運算也被稱作連接、綁定或堆疊。numpy有一個用於合並原始Numpy數組的concatenation函數。concatenate是Numpy的方法,

而concate是pandas的方法。

concatenate連接:

arr=np.arange(12).reshape((3,4))
print arr
#輸出的結果如下:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
print np.concatenate([arr,arr],axis=1) #axis=1是列
#輸出的結果如下:
# [[ 0  1  2  3  0  1  2  3]
#  [ 4  5  6  7  4  5  6  7]
#  [ 8  9 10 11  8  9 10 11]]

concate連接:

# 如果各對象其他軸上的索引不同,那些軸應該是做並集還是交集?
# 結果對象中的分組需要各不相同嗎?
# 用於連接的軸axis重要嗎?

concate用於解決上面的三個問題,它與concatenate沒多大區別,只是多了一些參數

(1)三個沒有重疊索引的Series,對這些對象調用concat可以將值和索引粘合在一起
s1=Series([0,1],index=[‘a‘,‘b‘])
s2=Series([2,3,4],index=[‘c‘,‘d‘,‘e‘])
s3=Series([5,6],index=[‘f‘,‘g‘])
print s1
# a    0
# b    1
print s2
# c    2
# d    3
# e    4
print s3
# f    5
# g    6
print pd.concat([s1,s2,s3])
#輸出結果如下:
# a    0
# b    1
# c    2
# d    3
# e    4
# f    5
# g    6

(2)默認情況下,concat是在axix=0行上作用的,最終產生一個新的Series.如果傳入axis=1,則結果就會變成一個DataFrame(axis=1是列)
#series行向合並,本來series只有行索引,故產生一個新的Series.如果列合並,有幾個數組,列不一定相同,所以會產生一個DataFrame
print pd.concat([s1,s2,s3],axis=1)
#輸出結果如下:
#      0    1    2
# a  0.0  NaN  NaN
# b  1.0  NaN  NaN
# c  NaN  2.0  NaN
# d  NaN  3.0  NaN
# e  NaN  4.0  NaN
# f  NaN  NaN  5.0
# g  NaN  NaN  6.0

(3)這種情況下,另外一條軸上沒有重疊,從索引的有序並集上就可以看出。。傳入join=‘inner‘即可得到它們的交集
s4=pd.concat([s1*5,s3])
print pd.concat([s1,s4],axis=1)
#輸出結果如下:
#      0  1
# a  0.0  0
# b  1.0  5
# f  NaN  5
# g  NaN  6
print pd.concat([s1,s4],axis=1,join=‘inner‘)
#輸出結果如下:
#    0  1
# a  0  0
# b  1  5

(4)可以通過join_axes指字要在其他軸上使用的索引
print pd.concat([s1,s4],axis=1,join_axes=[[‘a‘,‘c‘,‘b‘,‘e‘]])
#輸出結果如下:
#      0    1
# a  0.0  0.0
# c  NaN  NaN
# b  1.0  5.0
# e  NaN  NaN

(5)不過有個問題,參與連接的片段在結果中區分不開。假設你想要在連接軸上創建一個層次化索引。使用keys參數即可達到目的
result=pd.concat([s1,s1,s3],keys=[‘one‘,‘two‘,‘three‘])
print result
#輸出結果如下:
# one    a    0
#        b    1
# two    a    0
#        b    1
# three  f    5
#        g    6
# dtype: int64
print result.unstack()
#輸出結果如下:
#          a    b    f    g
# one    0.0  1.0  NaN  NaN
# two    0.0  1.0  NaN  NaN
# three  NaN  NaN  5.0  6.0

(6)如果沿著axis=1對Series進行合並,則keys就會成為DataFrame的列頭
print pd.concat([s1,s2,s3],axis=1,keys=[‘one‘,‘two‘,‘three‘])
#輸出結果如下:
#    one  two  three
# a  0.0  NaN    NaN
# b  1.0  NaN    NaN
# c  NaN  2.0    NaN
# d  NaN  3.0    NaN
# e  NaN  4.0    NaN
# f  NaN  NaN    5.0
# g  NaN  NaN    6.0

(7)同樣的邏輯對DataFrame對象也是一樣:
df1=DataFrame(np.arange(6).reshape(3,2),index=[‘a‘,‘b‘,‘c‘],
              columns=[‘one‘,‘two‘])
df2=DataFrame(5+np.arange(4).reshape(2,2),index=[‘a‘,‘c‘],
              columns=[‘three‘,‘four‘])
print pd.concat([df1,df2],axis=1,keys=[‘level1‘,‘level2‘])
#輸出結果如下:
#   level1     level2
#      one two  three four
# a      0   1    5.0  6.0
# b      2   3    NaN  NaN
# c      4   5    7.0  8.0

(8)如果傳入的不是列表而是一個字典,則字黃的鍵就會被做Keys選項的值。
print pd.concat({‘level1‘:df1,‘level2‘:df2},axis=1)
#   level1     level2
#      one two  three four
# a      0   1    5.0  6.0
# b      2   3    NaN  NaN
# c      4   5    7.0  8.0

(9)此外還有兩個用於管理層次化索引創建方式的參數:
  a:key,names
print pd.concat([df1,df2],axis=1,keys=[‘level1‘,‘level2‘],
                names=[‘upper‘,‘lower‘])
#輸出的結果如下:
# upper level1     level2
# lower    one two  three four
# a          0   1    5.0  6.0
# b          2   3    NaN  NaN
# c          4   5    7.0  8.0

  b:ignore_index=True
df1=DataFrame(np.random.randn(3,4),columns=[‘a‘,‘b‘,‘c‘,‘d‘])
df2=DataFrame(np.random.randn(2,3),columns=[‘b‘,‘d‘,‘a‘])
print df1
print df2
#在這種情況下,傳入ignore_index=True即可:
print pd.concat([df1,df2],ignore_index=True)
#輸出結果如下:
#           a         b         c         d
# 0 -0.540071 -0.225394 -0.851317 -1.638987
# 1  0.163700  1.375732  0.255257  1.290061
# 2  0.787074  0.137692  0.929145 -0.793582
# 3 -0.502263  0.717226       NaN -1.224583
# 4 -0.023067 -0.556030       NaN -0.819273

concat函數的參數
參數 說明
objs 參與連接的pandas對象的列表或字典。唯一必需的參數
axis 指明連接的軸向,默認為0
join “inner”、“outer”其中之一,默認為"outer".指明其他軸向上的索引是按交集(inner)
還是並集(outer)進行合並
join_axes 指明用於其他n-1條軸的索引,不執行並集/交集運算
keys 與連接對象有關的值,用於形成連接軸向上的層次化索引。可以是任意值的列表或數組、元組數組、
數組列表(如果將levels設置成多級數組的話)
levels 指定用作層次化索引各級別上的索引,如果設置了keys的話
names 用於創建分層級別的名稱,如果設置了keys和levels的話
verify_integrity 檢查結果對象新軸上的重復情況,如果發現則引發異常。默認(False)允許重復
ignore_index 不保留連接軸上的索引,產生一組新索引

合並重疊數據:numpy.where, pd.combine_first

還有一種數據組合問題不能用簡單的合並(merge)或連接(concatenation)運算來處理。

比如,可能有索引全部或部分重疊的兩個數據集。我們使用Numpy的where函數,它用於表達一種矢量化的if-else:

(1)Numpy的where

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

(1)Numpy的where
a=Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],
         index=[‘f‘,‘e‘,‘d‘,‘c‘,‘b‘,‘a‘])
b=Series(np.arange(len(a),dtype=np.float64),
         index=[‘f‘,‘e‘,‘d‘,‘c‘,‘b‘,‘a‘])
b[-1]=np.nan
print a
#輸出結果如下:
# f    NaN
# e    2.5
# d    NaN
# c    3.5
# b    4.5
# a    NaN
print b
#輸出結果如下:
# f    0.0
# e    1.0
# d    2.0
# c    3.0
# b    4.0
# a    NaN
print np.where(pd.isnull(a),b,a) #a如果是Nan,則用b的數據代替,否則還是a的值
#輸出結果如下:
# [ 0.   2.5  2.   3.5  4.5  nan]

(2)Series有一個combine_first方法,可以實現上面一樣的功能,而且會時行數據對齊

print b[:-2].combine_first(a[2:]) #b[:-2]的值若有nan則用a[2:]的值代替。但是b[:-2]是不包括右邊的倒數第二個b的,
# 則b的值用第一個4.5
#輸出結果如下:
# a    NaN
# b    4.5
# c    3.0
# d    2.0
# e    1.0
# f    0.0
#Series的combine_first方法實例:DataFrame也有combine_first方法
s1=pd.Series([1,np.nan])
s2=pd.Series([3,4])
print s1
# 0    1.0
# 1    NaN
print s2
# 0    3
# 1    4
print s1.combine_first(s2) #s1裏有nan就換成s2的值
# 0    1.0
# 1    4.0

(3)DataFrame的combine_first也是同上,因此可以將其看做:用參數對象中的數據為調用者對象的缺失數據"打補丁"

df1=DataFrame({‘a‘:[1.,np.nan,5.,np.nan],
               ‘b‘:[np.nan,2.,np.nan,6.],
               ‘c‘:range(2,18,4)})
df2=DataFrame({‘a‘:[5.,4.,np.nan,3.,7.],
               ‘b‘:[np.nan,3.,4.,6.,8.]})
print df1
#輸出結果如下:
#      a    b   c
# 0  1.0  NaN   2
# 1  NaN  2.0   6
# 2  5.0  NaN  10
# 3  NaN  6.0  14
print df2
#輸出結果如下:
#      a    b
# 0  5.0  NaN
# 1  4.0  3.0
# 2  NaN  4.0
# 3  3.0  6.0
# 4  7.0  8.0
print df1.combine_first(df2) #用df2裏的數據為df1中的數據為nan的數據打補丁
#輸出結果如下:
#      a    b     c
# 0  1.0  NaN   2.0
# 1  4.0  2.0   6.0
# 2  5.0  4.0  10.0
# 3  3.0  6.0  14.0
# 4  7.0  8.0   NaN
  1. 重塑和軸向旋轉:

pandas對象中有許多用於重新排列表格型數據的基礎運算。這些函數也稱作重塑或軸向旋轉運算。

(1)stack:將數據的列"旋轉"為行。(將DataFrame轉換成Series,而Series無stack方法)

(2)unstack:與stack相反的操作,將數據的行“旋轉”為列。(將Series轉換成DataFrame,DataFrame還是DataFrame)

重塑層次化索引:

層次化索引為DataFrame數據的重排任務提供了一個具有良好一致性的方式。主要功能有以下二個方法:

層次化索引為DataFrame數據的
stack:將數據的列"旋轉"為行,將DataFrame轉換成Series,Series無stack()方法
unstack:將數據的行"旋轉"為列,將Series轉換成DataFrame了,DataFrame還是DataFrame

(1)將DataFrame的列旋轉為行:DataFrame.stack()
data=DataFrame(np.arange(6).reshape((2,3)),
               index=pd.Index([‘Ohio‘,‘Colorado‘],name=‘state‘),
               columns=pd.Index([‘one‘,‘two‘,‘three‘],name=‘number‘))
print data
#輸出結果如下:
# number    one  two  three
# state
# Ohio        0    1      2
# Colorado    3    4      5
result=data.stack()
print result
# #輸出結果如下:
# # state     number
# # Ohio      one       0
# #           two       1
# #           three     2
# # Colorado  one       3
# #           two       4
# #           three     5

 (2)對於一個層次化索引的Series,可以用unstack將其重排為一個DataFrame.
print result.unstack()
#輸出結果如下:
# number    one  two  three
# state
# Ohio        0    1      2
# Colorado    3    4      5
默認情況下,unstack操作的是最內層(stack也是如此)。傳入分層級別的編號或名稱即可對其他級別進行unstack操作
print result.unstack(0)
#輸出結果如下:
# state   Ohio  Colorado
# number
# one        0         3
# two        1         4
# three      2         5
print result.unstack(‘state‘)
#輸出結果如下:
# state   Ohio  Colorado
# number
# one        0         3
# two        1         4
# three      2         5

(3)如果不是所有級別值都能在各分組中找到的話,則unstack操作可能會引入缺失數據:
s1=Series([0,1,2,3],index=[‘a‘,‘b‘,‘c‘,‘d‘])
s2=Series([4,5,6],index=[‘c‘,‘d‘,‘e‘])
data2=pd.concat([s1,s2],keys=[‘one‘,‘two‘])
print data2
#輸出結果如下:
# one  a    0
#      b    1
#      c    2
#      d    3
# two  c    4
#      d    5
#      e    6
# dtype: int64
print data2.unstack()
#輸出結果如下:
#        a    b    c    d    e
# one  0.0  1.0  2.0  3.0  NaN
# two  NaN  NaN  4.0  5.0  6.0

(4)stack默認會濾除缺失數據,因此該運算是可逆的:
# print data2.stack() #報錯‘Series‘ object has no attribute ‘stack‘
#可以對data2.unstack()後的DataFrame進行stack()
print data2.unstack().stack(dropna=False) #DataFrame轉換成Series了,且列變成行了
#輸出結果如下:
# one  a    0.0
#      b    1.0
#      c    2.0
#      d    3.0
#      e    NaN
# two  a    NaN
#      b    NaN
#      c    4.0
#      d    5.0
#      e    6.0
print data2.unstack().unstack() #data2.unstack()的行變成列
#輸出結果如下:
# a  one    0.0
#    two    NaN
# b  one    1.0
#    two    NaN
# c  one    2.0
#    two    4.0
# d  one    3.0
#    two    5.0
# e  one    NaN
#    two    6.0

(5)對DataFrame進行unstack操作時,作為旋轉軸的級別將會成為結果中的最低級別
df=DataFrame({‘left‘:result,‘right‘:result+5},
             columns=pd.Index([‘left‘,‘right‘],name=‘side‘))
print df
#result的內容如下:
# # state     number
# # Ohio      one       0
# #           two       1
# #           three     2
# # Colorado  one       3
# #           two       4
# #           three     5
#df的結果如下:
# side             left  right
# state    number
# Ohio     one        0      5
#          two        1      6
#          three      2      7
# Colorado one        3      8
#          two        4      9
#          three      5     10
print df.unstack(‘state‘) #將state的行旋轉為列
#輸出結果如下:
# side   left          right
# state  Ohio Colorado  Ohio Colorado
# number
# one       0        3     5        8
# two       1        4     6        9
# three     2        5     7       10
print df.unstack(‘state‘).stack(‘side‘) #將上面的再stack將列為side的旋轉為行(即left,right)
#輸出結果如下:
# state         Colorado  Ohio
# number side
# one    left          3     0
#        right         8     5
# two    left          4     1
#        right         9     6
# three  left          5     2
#        right        10     7

將"長格式"轉換為"寬格式":

時間序列數據通常是以所謂的"長格式"(long)或"堆疊格式"(stacked)存儲在數據庫和CSV中的。

關系型數據庫通常是主鍵形式提供了關系的完整性,而且提供了更為簡單的查詢支持。但對於長格式的數據操作起來就不那麽輕松了。

而DataFrame可以把主鍵中不同的Item值分別形成一列,date列中的時間值則用作索引,可以用DataFrame的pivot方法完全可以實現這個轉換。

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

ldata=DataFrame({‘date‘:[‘1959-03-31 00:00:00‘,‘1959-03-31 00:00:00‘,‘1959-03-31 00:00:00‘,
                         ‘1959-06-30 00:00:00‘,‘1959-06-30 00:00:00‘,‘1959-06-30 00:00:00‘,
                         ‘1959-09-30 00:00:00‘,‘1959-09-30 00:00:00‘,‘1959-09-30 00:00:00‘,‘1959-12-31 00:00:00‘],
                 ‘item‘:[‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘],
                 ‘value‘:[‘2710.349‘,‘0.000‘,‘5.800‘,‘2778.801‘,‘2.340‘,‘5.100‘,‘2775.488‘,‘2.740‘,‘5.300‘,‘2785.204‘]

})
print ldata
#輸出結果如下:
#                   date     item     value
# 0  1959-03-31 00:00:00  realgdp  2710.349
# 1  1959-03-31 00:00:00     infl     0.000
# 2  1959-03-31 00:00:00    unemp     5.800
# 3  1959-06-30 00:00:00  realgdp  2778.801
# 4  1959-06-30 00:00:00     infl     2.340
# 5  1959-06-30 00:00:00    unemp     5.100
# 6  1959-09-30 00:00:00  realgdp  2775.488
# 7  1959-09-30 00:00:00     infl     2.740
# 8  1959-09-30 00:00:00    unemp     5.300
# 9  1959-12-31 00:00:00  realgdp  2785.204

(1)使用DataFrame的pivot的方法
pivoted=ldata.pivot(‘date‘,‘item‘,‘value‘)
print pivoted.head()
#輸出結果如下:
# item                  infl   realgdp  unemp
# date
# 1959-03-31 00:00:00  0.000  2710.349  5.800
# 1959-06-30 00:00:00  2.340  2778.801  5.100
# 1959-09-30 00:00:00  2.740  2775.488  5.300
# 1959-12-31 00:00:00   None  2785.204   None

(2)前兩個參數值分別用作行和列索引的列名,最後一個參數值則是用於填充DataFrame的數據列的列名。
#假設有兩個需要參與重塑的數據列:
ldata[‘value2‘]=np.random.randn(len(ldata))
print ldata[:10]
#輸出結果如下:
#                   date     item     value    value2
# 0  1959-03-31 00:00:00  realgdp  2710.349  0.935557
# 1  1959-03-31 00:00:00     infl     0.000  1.609324
# 2  1959-03-31 00:00:00    unemp     5.800 -0.753734
# 3  1959-06-30 00:00:00  realgdp  2778.801 -0.668879
# 4  1959-06-30 00:00:00     infl     2.340 -0.256601
# 5  1959-06-30 00:00:00    unemp     5.100  0.537770
# 6  1959-09-30 00:00:00  realgdp  2775.488  1.073817
# 7  1959-09-30 00:00:00     infl     2.740 -0.027340
# 8  1959-09-30 00:00:00    unemp     5.300 -0.531161
# 9  1959-12-31 00:00:00  realgdp  2785.204  0.706080

(3)如果忽略掉最後一個參數,得到的DataFrame就會帶有層次化的列
pivoted=ldata.pivot(‘date‘,‘item‘)
print pivoted[:5]
#輸出結果如下:
#                      value                     value2
# item                  infl   realgdp  unemp      infl   realgdp     unemp
# date
# 1959-03-31 00:00:00  0.000  2710.349  5.800 -0.505690 -1.090732 -2.123859
# 1959-06-30 00:00:00  2.340  2778.801  5.100 -0.940028 -2.204997 -1.195357
# 1959-09-30 00:00:00  2.740  2775.488  5.300 -0.636424  0.510898  1.105585
# 1959-12-31 00:00:00   None  2785.204   None       NaN -0.203154       NaN

(4)註意,pivot其實只是一個快捷方式而己:用set_index創建層次化索引,再用unstack重塑。
unstacked=ldata.set_index([‘date‘,‘item‘]).unstack(‘item‘)
print unstacked[:7]
#輸出結果如下:
#                      value                     value2
# item                  infl   realgdp  unemp      infl   realgdp     unemp
# date
# 1959-03-31 00:00:00  0.000  2710.349  5.800 -0.380805 -2.499867 -1.398593
# 1959-06-30 00:00:00  2.340  2778.801  5.100 -0.168914  0.435372 -1.454938
# 1959-09-30 00:00:00  2.740  2775.488  5.300 -0.297850 -1.693196  1.615807
# 1959-12-31 00:00:00   None  2785.204   None       NaN  1.551105       NaN

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

df = pd.DataFrame({‘foo‘: [‘one‘, ‘one‘, ‘one‘, ‘two‘, ‘two‘,
                           ‘two‘],
                   ‘bar‘: [‘A‘, ‘B‘, ‘C‘, ‘A‘, ‘B‘, ‘C‘],
                   ‘baz‘: [1, 2, 3, 4, 5, 6],
                   ‘zoo‘: [‘x‘, ‘y‘, ‘z‘, ‘q‘, ‘w‘, ‘t‘]})
print df
#輸出結果如下:
#   bar  baz  foo zoo
# 0   A    1  one   x
# 1   B    2  one   y
# 2   C    3  one   z
# 3   A    4  two   q
# 4   B    5  two   w
# 5   C    6  two   t
print df.pivot(index=‘foo‘,columns=‘bar‘)[‘baz‘] #行索引foo,列bar,值baz
#輸出結果如下:
# bar  A  B  C
# foo
# one  1  2  3
# two  4  5  6
print df.pivot(index=‘foo‘,columns=‘bar‘,values=‘baz‘) #與上面的一致
# print df.pivot(index=‘foo‘,columns=‘bar‘,values=[‘baz‘, ‘zoo‘])
#若是兩行的索引一樣的話會報錯,因為值就不知道對應哪個了
#如下例中bar中的兩個索一樣
df=pd.DataFrame({"foo":[‘one‘,‘one‘,‘two‘,‘two‘],
                 "bar":[‘A‘,‘A‘,‘B‘,‘C‘],
                 "baz":[1,2,3,4]})
print df
print df.pivot(index=‘foo‘,columns=‘bar‘,values=‘baz‘) #報錯,foo,bar為[one,A]不知道對應哪個值了,兩個一樣的索引
  1. 數據轉換:

前面講的都是數據重排,另一類重要操作則是過濾、清理以及其它的轉換工作。

(1)drop_duplicates:刪除重復數據

(2)map:函數或映射進行數據轉換(map,lambda),map用於修改對象的子集

(3)fillna: 用於填充缺失數據,看做值替換的一種特殊情況。或者用pandas的replace方法替換缺失值(與python的str.replace方法一樣)

(4)rename:復制DataFrame並對其行索引和列標簽進行修改。若要就地修改某個數據集,傳入inplace=True即可

(5)cut:將數據劃分階段(即元面)例不同的年齡階段,它返回的Categorical對象。而qcut是根據樣本分位數對數據進行劃分(可以等分)

(6)abs:過濾絕對值,np.abs(data)>3取絕對值>3的數。

(7)np.sign:過濾的區間為-1到1的數組,表示原始值的符號。

(8)take:選取子集,從DataFrame或Series中選取部分子集

(9)get_dummies:DataFrame的某一列中有多個不同的值,可將該列的值作為列名,其值全為1和0.例:第一行只有a的值,則a為1,其它為0

                        Series只有panda.str.get_dummies.

pandas數據大發888平臺出租規整化:清理、轉換、合並、重塑