pandas 的數據結構(Series, DataFrame)


Pandas 講解

Python Data Analysis Library 或 pandas 是基於NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。

Pandas 納入了大量庫和一些標准的數據模型,提供了高效地操作大型數據集所需的工具。

pandas提供了大量能使我們快速便捷地處理數據的函數和方法。你很快就會發現,它是使Python成為強大而高效的數據分析環境的重要因素之一。

Series:一維數組,與Numpy中的一維array類似。
    二者與Python基本的數據結構List也很相近,其區別是:List中的元素可以是不同的數據類型,
    而Array和Series中則只允許存儲相同的數據類型,這樣可以更有效的使用內存,提高運算效率。
Time- Series:以時間為索引的Series。
DataFrame:二維的表格型數據結構。很多功能與R中的data.frame類似。
      可以將DataFrame理解為Series的容器。以下的內容主要以DataFrame為主。
Panel :三維的數組,可以理解為DataFrame的容器。

 ---------------------------------------------------

Series

Series 是一種類似於一維數組的對象, 它由一組數據(各種numpy數據類型)以及一組與之相關的數據標簽(索引)組成。

"""
In [1]: from pandas import Series

In [2]: from pandas import DataFrame

In [3]: obj = Series([4, 7, -5, 3])

In [4]: obj
Out[4]:
0    4
1    7
2   -5
3    3
dtype: int64
"""

 

Series 索引,指定索引(也就是左邊的列)

通過 上面的例子, 我們知道Series的字符表現形式為索引在左邊, 值在右邊。沒有指定索引,
那么索引會自動從0開始的整數型索引

可以通過Series的values和index屬性獲取其數組表示形式和索引對象。

 

"""
In [5]: obj.values
Out[5]: array([ 4,  7, -5,  3])

In [6]: obj.index
Out[6]: RangeIndex(start=0, stop=4, step=1)

"""

 

那么我們可以自定義索引

In [7]: obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])

In [8]: obj2
Out[8]:
d    4
b    7
a   -5
c    3
dtype: int64

In [9]: obj2.index
Out[9]: Index([u'd', u'b', u'a', u'c'], dtype='object')

索引賦值

In [11]: obj2['d'] = 9

In [12]: obj2
Out[12]:
d    9
b    7
a   -5
c    3
dtype: int64

索引取值

In [13]: obj2[["a", "b", "c"]]
Out[13]:
a   -5
b    7
c    3
dtype: int64

索引值映射

In:'b' in obj2
Out:True

In:'f' in obj2
Out:False

 

通過字典創建Series

"""
In [14]: sdata = {"Ohio":3500, "Texas":71000, "Oregon":16000, "Utah":51000}

In [15]: obj3 = Series(sdata)

In [16]: obj3
Out[16]:
Ohio       3500
Oregon    16000
Texas     71000
Utah      51000
dtype: int64
"""

 

索引匹配值和判斷缺失

相對應Series也可以匹配對應的索引,如果找不到結果為NaN(非數字),pandas中用於表示缺失的數據
同時isnull和notnull函數用於檢測缺失數據。

In [17]: states = ['California', 'Ohio', 'Oregon', 'Texas']

In [18]: obj4 = Series(sdata, index=states)

In [19]: obj4
Out[19]:
California        NaN
Ohio           3500.0
Oregon        16000.0
Texas         71000.0
dtype: float64

 

In [22]: pd.isnull(obj4)
Out[22]:
California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool
-------------
In [23]: pd.notnull(obj4)
Out[23]:
California    False
Ohio           True
Oregon         True
Texas          True
dtype: bool
-----------
In [24]: obj4.isnull()
Out[24]:
California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool

  

Series 數據對齊

In [25]: obj3 + obj4
Out[25]:
California         NaN
Ohio            7000.0
Oregon         32000.0
Texas         142000.0
Utah               NaN
dtype: float64

name屬性

Series 對象本身及其索引都有一個name屬性, 該屬性跟pandas其他的關鍵功能關系非常密切

 

In [26]: obj4.name = 'population'
In [27]: obj4.index.name = 'state'
In [29]: obj4
Out[29]:
state
California        NaN
Ohio           3500.0
Oregon        16000.0
Texas         71000.0
Name: population, dtype: float64

 

Series修改索引名稱

Series 的索引也可以通過索引的方式就地修改

In [30]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']

In [31]: obj
Out[31]:
Bob      4
Steve    7
Jeff    -5
Ryan     3
dtype: int64

 --------------------------------------------------------

DataFrame及常用方法

    ix  標簽索引
    T   index和columns變換方向
    index
    reindex

 

DataFrame 是一個表格行的數據結構, 他含有一組有序的列,每列可以是不同的值類型
(數值,字符串,布爾值等)。
DataFrame既有行索引也有列索引,他可以被看做是由Series組成的字典(共用同一個索引)
跟其他類似的數據結構相比,DataFrame中面向行和面向列的操作基本上是平衡的。
DataFrame 是以二維數據結構保存數據的

 

構建DataFrame

最常用的一種是直接傳入一個有等長列表或Numpy數組組成的字典

In [2]: data = {"state": ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year':[2000, 2001, 2002, 2001, 2002], 'pop':[1.5, 1.7, 3.6, 2.4, 2.9]}

In [3]: from pandas import Series, DataFrame

In [4]: DataFrame(data)
Out[4]:
   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002

另一種嵌套字典生成DataFrame

In [29]: pop = {'Nevada': {2001:2.4, 2003:2.9}, 'Ohio':{2000:1.5, 2001:1.7, 2002:3.6}}

In [30]: frame3 = Dataframe(pop)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-30-da7c61f3c94a> in <module>()
----> 1 frame3 = Dataframe(pop)

NameError: name 'Dataframe' is not defined

In [31]: frame3 = DataFrame(pop)

In [32]: frame3
Out[32]:
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     NaN   3.6
2003     2.9   NaN

 

第三種:

>>> d = [{"a":1,"b":2}, {"b":1,"a":2}]
>>> D = DataFrame(d)

>>> D
a b
0 1 2
1 2 1

 

 第四種

In [52]: data = DataFrame(np.arange(16).reshape((4,4)), index=["Ohio", "Colorado", "Utah", "New York"], columns=["one", "two", "three", "four"])

In [53]: data
Out[53]:
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

 

DataFrame 的列按照順序進行排列(列排序)

In [6]: DataFrame(data, columns=['year', 'state', 'pop'])

In [7]: data
Out[7]:
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9

跟Series一樣,如果傳入的列在數據中找不到, 就會產生NA值

In [11]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five'])

In [12]: frame2
Out[12]:
       year   state  pop debt
one    2000    Ohio  1.5  NaN
two    2001    Ohio  1.7  NaN
three  2002    Ohio  3.6  NaN
four   2001  Nevada  2.4  NaN
five   2002  Nevada  2.9  NaN

 

axis=0和1分別的表格的縱軸和橫軸

通過字典標記(索引)的方式獲取一個Series

In [13]: frame2['year']    也可以寫成frame2.year
Out[13]:
one      2000
two      2001
three    2002
four     2001
five     2002
Name: year, dtype: int64

返回的Series擁有同樣的索引

行也可以通過位置或名稱的方式進行獲取,例如用索引字段ix

In [14]: frame2.ix['three']
Out[14]:
year     2002
state    Ohio
pop       3.6
debt      NaN
Name: three, dtype: object

 

索引賦值

In [23]: df2.loc['d'] = [i*0 for i in range(len(df2.columns))]

In [24]: df2
Out[24]: 
            b     d     e  dd
Uhahdd    0.0   1.0   2.0   0
Ohiodd    3.0   4.0   5.0   0
Texasdd   6.0   7.0   8.0   0
Oregondd  9.0  10.0  11.0   0
dd        1.0   2.0   3.0   4
d         0.0   0.0   0.0   0

列表推到式還可以寫成

map(lambda x:0 if x >0 else 0, a)

 

列賦值

列可以通過賦值的方式進行修改。例如我們可以給那個空的‘debt’列附上一個附上一個標量或一組值

In [15]: frame2['debt'] = 16.5

In [16]: frame2
Out[16]:
       year   state  pop  debt
one    2000    Ohio  1.5  16.5
two    2001    Ohio  1.7  16.5
three  2002    Ohio  3.6  16.5
four   2001  Nevada  2.4  16.5
five   2002  Nevada  2.9  16.5

 

In [17]: import numpy as np

In [18]: frame2['debt'] = np.arange(5.)

In [19]: frame2
Out[19]:
       year   state  pop  debt
one    2000    Ohio  1.5   0.0
two    2001    Ohio  1.7   1.0
three  2002    Ohio  3.6   2.0
four   2001  Nevada  2.4   3.0

 

將一個列表或數組賦值給某個列時, 如果賦值的是Series, 就會精確匹配DataFrame的索引,
所有的空值將會被填上缺失值。

n [20]: val = Series([1.2, 1.3, -1.2], index=['two', 'four', 'five'])

In [21]: frame2['debt'] = val

In [22]: frame2
Out[22]:
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7   1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4   1.3
five   2002  Nevada  2.9  -1.2

創建列

可以創建新列

In [23]: frame2['eastern'] = frame2.state == 'Ohio'

In [24]: frame2
Out[24]:
       year   state  pop  debt eastern
one    2000    Ohio  1.5   NaN    True
two    2001    Ohio  1.7   1.2    True
three  2002    Ohio  3.6   NaN    True
four   2001  Nevada  2.4   1.3   False
five   2002  Nevada  2.9  -1.2   False

刪除列

In [26]: del frame2['eastern']

In [27]: frame2
Out[27]:
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7   1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4   1.3
five   2002  Nevada  2.9  -1.2

In [28]: frame2.columns
Out[28]: Index([u'year', u'state', u'pop', u'debt'], dtype='object')

 

結果 行、列倒置,調換位置

In [33]: frame3.T
Out[33]:
        2000  2001  2002  2003
Nevada   NaN   2.4   NaN   2.9
Ohio     1.5   1.7   3.6   NaN

內層字典的鍵會被合並、排序以形成最終的索引。如果顯示指定了索引, 則按照索引走

In [35]: DataFrame(pop, index=[2001, 2002, 2003, 2004])
Out[35]:
      Nevada  Ohio
2001     2.4   1.7
2002     NaN   3.6
2003     2.9   NaN
2004     NaN   NaN

也可以根據索引key和切片取值賦值

In [36]: pdata = {'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2]}

In [39]: DataFrame(pdata)
Out[39]:
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     NaN   3.6

可以輸入給DataFrame構造器的數據

二維ndarray   數據矩陣,還可以傳入行標和列標
由數組、列表和元組組成的字典  每個序列會變成DataFrame的一列。 所有序列的長度必須相同
Numpy的結構化/記錄數組  類似於“由數組組成的字典”
由Series組成的字典    每個Series會成為一列。如果沒有顯示指定索引, 則各Series的索引會被合並成結果的行索引
由字典組成的字典    各內層字典會成為一列。鍵會被合並成結果的行索引,跟"由Series組成的字典"的情況一樣
字典或Series的列表 各項將會成為DataFrame的一行。字典鍵或Series索引的並集將會成為DataFrame的列標
由列標或元組組成的列表     類似於“二維ndarray”
另一個DataFrame    該DataFrame的索引將會被沿用,除非顯示指定了其他索引
Numpy的MaskedArray   類似於"二維ndarray"的情況, 只是掩碼值在結果DataFrame會變成NA/缺失值

 

行標,列標設置別名

In [40]: frame3.index.name = "year"; frame3.columns.name = "state"

In [41]: frame3
Out[41]:
state  Nevada  Ohio
year
2000      NaN   1.5
2001      2.4   1.7
2002      NaN   3.6
2003      2.9   NaN

獲取數據

DataFrame以二維ndarray的形式返回數據

In [42]: frame3.values
Out[42]:
array([[ nan,  1.5],
       [ 2.4,  1.7],
       [ nan,  3.6],
       [ 2.9,  nan]])

如果DataFrame各列的數據類型不同, 則值數組的數據類型就會選用能兼容所有列的數據類型

 

----------------------------------------

索引對象

pandas的索引對象負責管理軸標簽和其他元數據(比如軸名稱等。)構建Series或Data Frame時,所用到的任何數組或其他序列的標簽都會被轉換成一個Index。

In [1]: from pandas import Series, DataFrame

In [2]: obj = Series(range(3), index=["a", "b", "c"])

In [3]: index = obj.index

In [4]: index
Out[4]: Index([a, b, c], dtype=object)

In [5]: obj
Out[5]:
a    0
b    1
c    2

In [6]: index[1:]
Out[6]: Index([b, c], dtype=object)

而索引是不可修改的

那么根據上面的例子,報錯,證明索引是不可以修改的

In [7]: index[1]
Out[7]: 'b'

In [8]: index[1] = "d"
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
C:\Python27\<ipython-input-8-092906bbf8a9> in <module>()
----> 1 index[1] = "d"

C:\Python27\lib\site-packages\pandas\core\index.pyc in __setitem__(self, key, value)
    307     def __setitem__(self, key, value):
    308         """Disable the setting of values."""
--> 309         raise Exception(str(self.__class__) + ' object is immutable')
    310
    311     def __getitem__(self, key):

Exception: <class 'pandas.core.index.Index'> object is immutable

 

而這樣做的目的是index對象在多個數據結果之間安全共享

In [11]: index = pd.Index(np.arange(3))

In [12]: index
Out[12]: Int64Index([0, 1, 2], dtype=int64)

In [13]: obj2 = Series([1.5, -2.5, 0], index=index)

In [14]: obj2
Out[14]:
0    1.5
1   -2.5
2    0.0

證明是共享的

In [16]: obj2.index is index
Out[16]: True

 

pandas中主要的Index對象

Index  最泛化的Index對象, 將軸標簽表示為一個由python對象組成的Numpy數組
Int64Index  針對整數的特殊Index
MultiIdex  “層次化”索引對象, 表示單個軸上的多層索引。可以看做由元組組成的數組
DatatimeIndex  存儲納秒級時間戳(用NumPy的datatime64類型表示)
PeriodIndex  針對Period數據(時間jiange)的特殊Index

Index的方法和屬性

append    連接另一個index對象,產生另一個新的Index
diff    計算差集,並得到一個index
intersection    計算交集
union    計算並集
isin    計算一個指示各值是否都包含在參數集合中的布爾型數據
delete    刪除索引i處的元素,bing得到一個新的Index
drop    刪除傳入的值,並得到新的Index
insert  將元素插入到索引i出, 並得到新的index
is_monotonic  當各元素均大於等於前一個元素是,返回True
is_unique  當index沒有重復值時,返回True
unique  計算Index中唯一值的數組
In [42]: index3.delete(2)
Out[42]: Int64Index([0, 1, 4, 5, 6], dtype=int64)

In [28]: index3 = index.append(Index2)

In [29]: index3
Out[29]: Int64Index([0, 1, 2, 4, 5, 6], dtype=int64)

  

reindex重新索引 (fill_value 設置默認值)

pandas對象的一個重要方法是reindex, 其作用是創建一個適應新索引的新對象。

而調用Series的reindex將會根據新索引進行重排。如果某個索引值不存在,就引入缺失值。

obj = Series([4.5, 7.l2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])

In [25]: obj2 = obj.reindex([i for i in list("abcde")], fill_value=0)
In [26]: obj2
Out[26]:
a   -5.2
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64

 

但是注意:時間序列這樣的有序數據, 重新索引時可能需要做一些插值處理。method選項即可達到目的

例如使用ffill可以實現向前值填充:

 

In [27]: obj3 = Series(["blue", "purple", "yellow"], index=[0, 2, 4])

In [28]: obj3.reindex(range(6), method="ffill")
Out[28]:
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object

In [29]: obj3
Out[29]:
0      blue
2    purple
4    yellow
dtype: object

 

reindex 可以重新 修改(行)索引、列, 或兩個都可以修改。傳入一個值默認為行索引

 

In [33]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=[i for i in list('abc')], columns=["Ohio", "Texas", "California"])

In [34]: frame
Out[34]:
   Ohio  Texas  California
a     0      1           2
b     3      4           5
c     6      7           8

In [35]: frame2 = frame.reindex([i for i in list("abcd")])

In [36]: frame2
Out[36]:
   Ohio  Texas  California
a   0.0    1.0         2.0
b   3.0    4.0         5.0
c   6.0    7.0         8.0
d   NaN    NaN         NaN

In [37]: states = ["Texas", "Utah", "California"]

In [38]: frame.reindex(columns=states)
Out[38]:
   Texas  Utah  California
a      1   NaN           2
b      4   NaN           5
c      7   NaN           8

In [39]: frame.ix[[i for i in list("abcd")], states]
Out[39]:
   Texas  Utah  California
a    1.0   NaN         2.0
b    4.0   NaN         5.0
c    7.0   NaN         8.0
d    NaN   NaN         NaN

 

 

-------------------------------------------------------------------

 Series 和 DataFrame 丟棄指定軸上的項  pandas刪除行

丟棄某條軸上的一個或多個項很簡單, 只要偶一個索引數組或列表即可。

而drop方法返回的是一個在指定軸上刪除了指定值的新對象。 

In [46]: obj = Series(np.arange(5.), index=[i for i in list("abcde")])

In [47]: obj
Out[47]:
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

In [48]: new_obj = obj.drop("c")

In [49]: new_obj
Out[49]:
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

In [50]: obj.drop(["b", "c"])
Out[50]:
a    0.0
d    3.0
e    4.0
dtype: float64

而DataFrame可以刪除任意軸上的索引值 

 

In [52]: data = DataFrame(np.arange(16).reshape((4,4)), index=["Ohio", "Colorado", "Utah", "New York"], columns=["one", "two", "three", "four"])

In [53]: data
Out[53]:
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

In [54]: data.drop(["Colorado", ""Ohio])
  File "<ipython-input-54-8d771dda6c46>", line 1
    data.drop(["Colorado", ""Ohio])
                                ^
SyntaxError: invalid syntax


In [55]: data.drop(["Colorado", "Ohio"])
Out[55]:
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15

-------
In [57]: data.drop(["one"], axis=1)
Out[57]:
          two  three  four
Ohio        1      2     3
Colorado    5      6     7
Utah        9     10    11
New York   13     14    15

In [58]: data.drop(["one", "four"], axis=1)
Out[58]:
          two  three
Ohio        1      2
Colorado    5      6
Utah        9     10
New York   13     14

---------------------------------------------

索引選取和過濾

Series

 Series 索引(obj[...])的工作方式類似與Numpy數組的索引,只不過Series的索引值不只是整數

In [8]: obj = Series(np.arange(4.), index = [i for i in list("abcd")])

In [9]: obj['b']
Out[9]: 1.0

In [10]: obj[1]
Out[10]: 1.0

In [11]: obj[2:4]
Out[11]:
c    2.0
d    3.0
dtype: float64

In [12]: obj[['b', 'c', 'd']]
Out[12]:
b    1.0
c    2.0
d    3.0
dtype: float64

In [13]: obj[[1, 3]]
Out[13]:
b    1.0
d    3.0
dtype: float64

In [14]: obj[obj<2]
Out[14]:
a    0.0
b    1.0
dtype: float64

 

利用索引賦值 

In [15]: obj['b':'c']
Out[15]:
b 1.0
c 2.0
dtype: float64

In [16]: obj['b':'c'] = 5

In [17]: obj
Out[17]:
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64

 

 DataFrame

而DataFrame進行索引就是獲取一個或多個列, 默認是columns
data【columns, index】的格式

 

In [18]: data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns = ['one', 'two', 'three', 'four'])

In [19]: data
Out[19]:
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

In [20]: data['two']
Out[20]:
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int64

In [21]: data[['three', 'one']]
Out[21]:
          three  one
Ohio          2    0
Colorado      6    4
Utah         10    8
New York     14   12

In [23]: data[:2]
Out[23]:
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7

In [24]: data[data['three'] > 5]
Out[24]:
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
View Code

值為bool類型

In [25]: data < 5
Out[25]:
            one    two  three   four
Ohio       True   True   True   True
Colorado   True  False  False  False
Utah      False  False  False  False
New York  False  False  False  False
View Code

重新賦值

In [26]: data[data < 5] = 0

In [27]: data
Out[27]:
          one  two  three  four
Ohio        0    0      0     0
Colorado    0    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
View Code

DataFrame.ix

如果DataFrame 使用標簽索引的話,就是index,需要引入專門的ix,其實就是調換方向
data【index, columns】

 

In [28]: data.ix['Colorado', ['three']]
Out[28]:
three    6
Name: Colorado, dtype: int64

In [29]: data.ix[['Colorado', 'Utah'], [3, 0, 1]]
Out[29]:
          four  one  two
Colorado     7    0    5
Utah        11    8    9

 

 

 

 

 

 

 

 

 

 

 

 

 

Chrome://flags/#enable-smooth-scrolling


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM