1. 程式人生 > 其它 >Pandas兩大主要資料結構之二——DataFrame

Pandas兩大主要資料結構之二——DataFrame

DataFrame

上篇介紹了Series,本篇主要介紹DataFrame。

DataFrame是一個表格型資料結構,它含有一組有序的列,每列可以是不同的值型別(數值、字串、布林值等)。

DataFrame既有行索引,也有列索引。與其它類似的資料結構相比(如R的data.frame),DataFrame面向行和麵向列的操作基本是平衡的。

DataFrame中的資料一般是以一個或者多個二維塊存放的,而不是列表、字典或者其它一維資料結構。

建立DataFrame

In [12]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
    ...:     ...: 'year': [2000, 2001, 2002, 2001, 2002],
    ...:     ...: 'pop': [1.5, 1.7, 3.6, 2.4, 3.9]}

In [13]: df = pd.DataFrame(data)

In [14]: df
Out[14]: 
    state  year  pop
0    Ohio  2000  1.5
1    Ohio  2001  1.7
2    Ohio  2002  3.6
3  Nevada  2001  2.4
4  Nevada  2002  3.9
  • 和Series一樣,如果傳入的列在資料中找不到的話,就會產生NA值
# 指定了列和行的順序
In [15]: df2 = pd.DataFrame(data, columns=['pop', 'state', 'year', 'debt'], index=['one', 'two', 'three', 'four', 'five'])

# 因為傳入的列不在字典中,因此結果中出現了缺失值
In [16]: df2
Out[16]: 
       pop   state  year debt
one    1.5    Ohio  2000  NaN
two    1.7    Ohio  2001  NaN
three  3.6    Ohio  2002  NaN
four   2.4  Nevada  2001  NaN
five   3.9  Nevada  2002  NaN

# 檢視df2的列名
In [17]: df2.columns
Out[17]: Index(['pop', 'state', 'year', 'debt'], dtype='object')

DataFrame的列訪問與處理

  • 獲取DataFrame列的兩種方式:字典標記形式、屬性形式
In [18]: df2.state
Out[18]: 
one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
Name: state, dtype: object

# 索引處使用列表的話,可以索引多列
In [19]: df2['state']
Out[19]: 
one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
Name: state, dtype: object
  • 通過賦值(一個值或一組值)的方式進行修改
# 屬性訪問
In [20]: df2.debt = 16.5

In [21]: df2
Out[21]: 
       pop   state  year  debt
one    1.5    Ohio  2000  16.5
two    1.7    Ohio  2001  16.5
three  3.6    Ohio  2002  16.5
four   2.4  Nevada  2001  16.5
five   3.9  Nevada  2002  16.5
# 字典型標記訪問
In [22]: df2['debt'] = np.arange(5.)

In [23]: df2
Out[23]: 
       pop   state  year  debt
one    1.5    Ohio  2000   0.0
two    1.7    Ohio  2001   1.0
three  3.6    Ohio  2002   2.0
four   2.4  Nevada  2001   3.0
five   3.9  Nevada  2002   4.0
  • 將列表或者陣列賦值給某一列時,其長度必須與DataFrame相匹配。如果賦值的是Series,就會精確匹配DataFrame的索引,所有空位都會補上缺失值。
In [24]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])

In [25]: df2.debt = val

In [26]: df2
Out[26]: 
       pop   state  year  debt
one    1.5    Ohio  2000   NaN
two    1.7    Ohio  2001  -1.2
three  3.6    Ohio  2002   NaN
four   2.4  Nevada  2001  -1.5
five   3.9  Nevada  2002  -1.7
  • 為不存在的列賦值會建立新列。
In [27]: df2['eastern'] = df2.state == 'Ohio'

In [28]: df2
Out[28]: 
       pop   state  year  debt  eastern
one    1.5    Ohio  2000   NaN     True
two    1.7    Ohio  2001  -1.2     True
three  3.6    Ohio  2002   NaN     True
four   2.4  Nevada  2001  -1.5    False
five   3.9  Nevada  2002  -1.7    False
  • del關鍵字:刪除某列,可以像在字典中那樣刪除DataFrame的某一列
In [29]: del df2['eastern']

In [30]: df2
Out[30]: 
       pop   state  year  debt
one    1.5    Ohio  2000   NaN
two    1.7    Ohio  2001  -1.2
three  3.6    Ohio  2002   NaN
four   2.4  Nevada  2001  -1.5
five   3.9  Nevada  2002  -1.7

DataFrame.drop方法

df.drop()方法。根據傳參刪除指定索引值,併產生新的索引

DataFrame.drop(labels=None,axis=0, index=None, columns=None, inplace=False)
  • 引數含義:

    • labels:要刪除的行或列,用列表給出

    • axis:預設為 0,指要刪除的是行,刪除列時需指定 axis 為 1

    • index :直接指定要刪除的行,刪除多行可以使用列表作為引數

    • columns:直接指定要刪除的列,刪除多列可以使用列表作為引數

    • inplace: 預設為 False,該刪除操作不改變原資料;inplace = True 時,改變原資料

    • 通過索引方式返回的列只是資料的檢視,並不是副本。因此對返回的Series所做的任何就地修改都會直接作用到源DataFrame上。通過Series的copy方法,可以顯式的複製列。

      這個地方極其容易出現SettingwithCopyWarning警告,具體的原因及解決辦法參考:Pandas 中 SettingwithCopyWarning 的原理和解決方案

  • Series刪除指定標記值

In [31]: obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])

In [32]: obj
Out[32]: 
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
  
In [33]: new_obj = obj.drop('c')

In [34]: new_obj
Out[34]: 
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
  • DataFrame刪除指定條目。使用axis來確定行、列
In [35]: data = pd.DataFrame(np.arange(16).reshape((4, 4)), index=['Ohio', 'Colorado', 'Utah', 'New 
    ...: york'], columns=['one', 'two', 'three', 'four'])

In [36]: data
Out[36]: 
          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
# axis預設為0,選擇行
In [37]: data.drop(['Colorado', 'Ohio'])
Out[37]: 
          one  two  three  four
Utah        8    9     10    11
New york   12   13     14    15
# axis=1或者axis='columns',選擇列
In [38]: data.drop('two', axis=1)
Out[38]: 
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New york   12     14    15

In [39]: data.drop('two', axis='columns')
Out[39]: 
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New york   12     14    15
  • 使用inplace=True,直接修改原物件
In [40]: obj.drop('c', inplace=True)

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

和drop方法一樣,還有一些其他的索引物件的方法和屬性。

方法 描述
append 將額外的索引物件貼上到原索引後,產生一個新的索引
difference 計算兩個索引的差集
intersection 計算兩個索引的交集
union 計算兩個索引的並集
isin 計算表示每一個值是否在傳值容器中的不二陣列
delete 將位置i的元素刪除,併產生新的索引
drop 根據傳參刪除指定索引值,併產生新的索引值
insert 在位置i插入元素,併產生新的索引
is_monotonic 如果索引序列遞增則返回True
is_unique 如果索引序列唯一則返回True
unique 計算索引的唯一值序列

DataFrame的行訪問與處理

  • 行選擇語法[:]
# 不包括選擇範圍末尾的2
In [48]: data[:2]
Out[48]: 
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
  • 行上的特殊索引符號loc(軸標籤)和iloc(整數標籤)
# 軸標籤
In [59]: data.loc['Ohio', ['one', 'three']]
Out[59]: 
one      0
three    2
Name: Ohio, dtype: int64

# 整數標籤
In [60]: data.iloc[0, [0, 2]]
Out[60]: 
one      0
three    2
Name: Ohio, dtype: int64
    
In [61]: data.iloc[[1, 2], [2, 0, 1]]
Out[61]: 
          three  one  two
Colorado      6    4    5
Utah         10    8    9

要時刻記得loc是用於標籤的,如果軸索引包含整數,那麼一定要使用標籤索引。

In [62]: ser = pd.Series(np.arange(3.))

In [63]: ser
Out[63]: 
0    0.0
1    1.0
2    2.0
dtype: float64

In [64]: ser.loc[:1]
Out[64]: 
0    0.0
1    1.0    # loc中的1為整數索引1,所以選擇到了這一項
dtype: float64

In [65]: ser.iloc[:1]
Out[65]: 
0    0.0    # iloc中的1為截止位置,所以只能選擇到這一項
dtype: float64
時來天地皆同力,運去英雄不自由。