1. 程式人生 > >03 -1 pandas 中 DataFrame理解與建立、索引、運算的詳解以及例項

03 -1 pandas 中 DataFrame理解與建立、索引、運算的詳解以及例項

DataFrame

DataFrame是一個【表格型】的資料結構,可以看做是【由Series組成的字典】(共用同一個索引)。DataFrame由按一定順序排列的多列資料組成。設計初衷是將Series的使用場景從一維拓展到多維。DataFrame既有行索引,也有列索引。

  • 行索引:index 代表樣本
  • 列索引:columns 代表維度
  • 值:values(numpy的二維陣列)

1)DataFrame的建立

最常用的方法是傳遞一個字典來建立。DataFrame以字典的鍵作為每一【列】的名稱,以字典的值(一個數組)作為每一列。

此外,DataFrame會自動加上每一行的索引(和Series一樣)。

同Series一樣,若傳入的列與字典的鍵不匹配,則相應的值為NaN。

DataFrame的建立

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

通過 DateFrame 函式 建立

df = DataFrame([1,2,3,4])
結果為:
	0
0	1
1	2
2	3
3	4
df = DataFrame([1,2,3,4],index=list("abcd"))
結果為:

	0
a	1
b	2
c	3
d	4
data = np.random.randint(0,150,size=(4,4))
index = ["張三","李四","王五","趙柳"]
columns = ["Math","Chinese","English","Python"]
df = DataFrame(data,index=index,columns=columns)
df
結果為:如下表
Math Chinese English Python
張三 10 145 15 11
李四 125 97 71 130
王五 149 79 149 67
趙柳 133 26 135 70

DataFrame屬性:values、columns、index、shape

df.values #所有的值
結果為:
array([[ 10, 145,  15,  11],
       [125,  97,  71, 130],
       [149,  79, 149,  67],
       [133,  26, 135,  70]])
df.columns # 每一列的標題
結果為:
Index(['Math', 'Chinese', 'English', 'Python'], dtype='object')
df.index #每一行的標題
結果為:
Index(['張三', '李四', '王五', '趙柳'], dtype='object')
df.shape
結果為:
(4, 4)

============================================

練習4:

根據以下考試成績表,建立一個DataFrame,命名為df:

    張三  李四
語文 150  0
數學 150  0
英語 150  0
理綜 300  0

============================================

data = [[150,0],[150,0],[150,0],[150,0]]
index = ["語文","數學","英語","理綜"]
columns = ["張三","李四"]
DataFrame(data=data,index=index,columns=columns)
張三 李四
語文 150 0
數學 150 0
英語 150 0
理綜 150 0

2)DataFrame的索引

(1) 對列進行索引

- 通過類似字典的方式
- 通過屬性的方式

可以將DataFrame的列獲取為一個Series。返回的Series擁有原DataFrame相同的索引,且name屬性也已經設定好了,就是相應的列名。

每一行是一個樣本 每一列是描述這個樣本的維度

df
Math Chinese English Python
張三 10 145 15 11
李四 125 97 71 130
王五 149 79 149 67
趙柳 133 26 135 70
df["Math"] # 按照字典的方式去從DataFrame裡取資料
結果為
張三     10
李四    125
王五    149
趙柳    133
Name: Math, dtype: int32
type(df["Math"])
結果為:pandas.core.series.Series
df.Math
結果為:
張三     10
李四    125
王五    149
趙柳    133
Name: Math, dtype: int32

(2) 對行進行索引

- 使用.loc[]加index來進行行索引
- 使用.iloc[]加整數來進行行索引

同樣返回一個Series,index為原來的columns。

df["張三"] # columns才能以索引的方式去取 index不行
結果為:
KeyError: '張三'
df.loc["張三"]
結果為:
Math        10
Chinese    145
English     15
Python      11
Name: 張三, dtype: int32
df.iloc[0]
結果為:
Math        10
Chinese    145
English     15
Python      11
Name: 張三, dtype: int32

總結

columns 才能以索引的形式去找 df[“列名”] df.列名

index 不能用索引的方式去找 只能用 loc[] 和 iloc[] 去定位內容

(3) 對元素進行索引

- 使用列索引
- 使用行索引(iloc[3,1]相當於兩個引數;iloc[[3,3]] 裡面的[3,3]看做一個引數)
- 使用values屬性(二維numpy陣列)

df["Math"].loc["張三"]   結果為:10
df["Math"].iloc[0]		結果為:10
df.loc["張三"]
結果為:
Math        10
Chinese    145
English     15
Python      11
Name: 張三, dtype: int32
type(df.loc["張三"])
結果為:
pandas.core.series.Series
df.loc["張三"].loc["Math"]
結果為:10

DataFrame自帶的方式

loc是DataFrame提供的定位元素的方法 ,可以傳入行的名稱去查詢整行,也可以 先傳入行名稱 ,再傳入列名稱 去定位元素,但是不能直接把列的名稱放前面

df.loc["張三","Math"]   結果為:10
df.loc["Math","張三"]  此查詢方法錯誤
# 終極方式
df.values[0,0]        結果為:10

【注意】 直接用中括號時:

  • 索引表示的是列索引
  • 切片表示的是行切片
df
Math Chinese English Python
張三 58 119 94 95
李四 31 7 42 124
王五 59 24 10 52
趙柳 24 2 88 3In [64]:
df["Math"] #df後面跟中括號作為索引的話 只能傳入列名 對列進行索引 
結果為:
張三     10
李四    125
王五    149
趙柳    133
Name: Math, dtype: int32
df[0:3] #df後面的中括號中 如果傳的是切片的方式 是對行進行切片
結果為:如下表
Math Chinese English Python
張三 10 145 15 11
李四 125 97 71 130
王五 149 79 149 67
df["Math":"English"] # 如果想對列進行切片
結果如下表:
Math Chinese English Python
df.iloc[:,0:2] # 需要通過iloc才能對列進行切片
Math Chinese
張三 10 145
李四 125 97
王五 149 79
趙柳 133 26

============================================

練習5:

使用多種方法對df進行索引和切片,並比較其中的區別

============================================

3)DataFrame的運算

(1) DataFrame和數值的運算

df+1 # 所有內容都加一
Math Chinese English Python
張三 11 146 16 12
李四 126 98 72 131
王五 150 80 150 68
趙柳 134 27 136 71
df["Python"] = df["Python"]+1 #兩種方法是一樣的效果,所以相當於加了兩次
df["Python"]+=1
df
Math Chinese English Python
張三 10 145 15 14
李四 125 97 71 133
王五 149 79 149 70
趙柳 133 26 135 73
df["Python"]["張三"] +=1
df
Math Chinese English Python
張三 10 145 15 15
李四 125 97 71 133
王五 149 79 149 70
趙柳 133 26 135 73

(2) DataFrame與DataFrame之間的運算

同Series一樣:

  • 在運算中自動對齊不同索引的資料
  • 如果索引不對應,則補NaN

下面是Python 操作符與pandas操作函式的對應表:

Python Operator Pandas Method(s)
+ add()
- sub(), subtract()
* mul(), multiply()
/ truediv(), div(), divide()
// floordiv()
% mod()
** pow()
df1 = DataFrame(np.random.randint(0,150,size=(5,5)),
                index=list("01234"),
                columns=list("ABCDE"))
df2 = DataFrame(np.random.randint(0,150,size=(5,5)),
                index=list("12345"),
                columns=list("ABCDE"))
display(df1,df2)
A B C D E
0 105 143 70 148 25
1 21 130 78 51 38
2 2 15 146 39 115
3 20 139 58 90 11
4 35 56 64 101 19
A B C D E
1 74 143 12 73 85
2 76 123 30 17 103
3 89 127 84 43 134
4 46 41 97 133 109
5 9 79 102 50 112
df1+df2 # 行和列索引名都對應 則 對應項相加
A B C D E
0 NaN NaN NaN NaN NaN
1 95.0 273.0 90.0 124.0 123.0
2 78.0 138.0 176.0 56.0 218.0
3 109.0 266.0 142.0 133.0 145.0
4 81.0 97.0 161.0 234.0 128.0
5 NaN NaN NaN NaN NaN

(3) DataFrame和Series之間的運算

df1 = DataFrame(data=np.random.randint(0,150,size=(5,5)),index=list("ABCDE"),columns=list("01234"))
s1 = Series(data=np.random.randint(0,150,size=5),index=list("01234"))
s2 = Series(data=np.random.randint(0,150,size=5),index=list("ABCDE"))
df1
0 1 2 3 4
A 143 31 15 91 81
B 8 64 78 57 9
C 142 116 23 98 114
D 30 113 39 86 113
E 7 0 48 39 122
s1
結果為:
0     44
1    101
2     67
3     63
4    124
dtype: int32
df1+s1 #series的索引和DataFrame的列索引對應 則每一行對應項相加
0 1 2 3 4
A 114 175 230 192 126
B 183 110 212 106 198
C 86 142 162 88 167
D 226 92 220 52 117
E 198 56 223 56 232
s2
結果為:
A      7
B     64
C     56
D    141
E     88
dtype: int32
df1
0 1 2 3 4
A 143 31 15 91 81
B 8 64 78 57 9
C 142 116 23 98 114
D 30 113 39 86 113
E 7 0 48 39 122
df1+s2 #預設是 Series的索引和DataFrame的列索引去對應 然後相加
0 1 2 3 4 A B C D E
A NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
B NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
C NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
D NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
E NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
df1.add(s2,axis="index")
0 1 2 3 4
A 150 38 22 98 88
B 72 128 142 121 73
C 198 172 79 154 170
D 171 254 180 227 254
E 95 88 136 127 210

============================================

練習6:

  1. 假設df1是期中考試成績,df2是期末考試成績,請自由建立df1和df2,並將相加,求期中期末平均值。
  2. 假設張三期中考試數學被發現作弊,要記為0分,如何實現?
  3. 李四因為舉報張三作弊立功,期中考試所有科目加100分,如何實現?
  4. 後來老師發現有一道題出錯了,為了安撫學生情緒,給每位學生每個科目都加10分,如何實現?

============================================

In [103]:

index = ["張三","李四"]
columns = ["語文","數學","英語"]
data = np.random.randint(0,150,size=(2,3))
df1 = DataFrame(data,index=index,columns=columns)
df1
語文 數學 英語
張三 136 11 96
李四 39 52 91
index = ["張三","李四"]
columns = ["語文","數學","英語"]
data = np.random.randint(0,150,size=(2,3))
df2 = DataFrame(data,index=index,columns=columns)
df2
語文 數學 英語
張三 28 30 57
李四 27 5 20
(df1+df2)/2
語文 數學 英語
張三 82.0 20.5 76.5
李四 33.0 28.5 55.5
df1["數學"].loc["張三"]    			結果為:11
df1.loc["張三"].loc["數學"]=0
df1
語文 數學 英語
張三 136 0 96
李四 39 52 91
df1.loc["李四"]+=100
df1
語文 數學 英語
張三 136 0 96
李四 139 152 191
df1+=10
df1
語文 數學 英語
張三 146 10 106
李四 149 162 201