Numpy&Pandas
Numpy & Pandas 簡介
此篇筆記參考來源為《莫煩Python》
運算速度快:numpy 和 pandas 都是采用 C 語言編寫, pandas 又是基於 numpy, 是 numpy 的升級版本。
消耗資源少:采用的是矩陣運算,會比 python 自帶的字典或者列表快好多
Numpy 學習
2.1 numpy屬性
ndim
:維度shape
:行數和列數size
:元素個數
舉例說明:
import numpy as np
array = np.array([[1,2,3],[2,3,4]]) #列表轉化為矩陣
print(array)
print(‘number of dim:‘,array.ndim) # 維度
# number of dim: 2
print(‘shape :‘,array.shape) # 行數和列數
# shape : (2, 3)
print(‘size:‘,array.size) # 元素個數
# size: 6
2.2 Numpy 的創建 array
array
:創建數組dtype
:指定數據類型zeros
:創建數據全為0ones
:創建數據全為1empty
:創建數據接近0arrange
:按指定範圍創建數據linspace
:創建線段
import numpy as np
#創建數組array
a = np.array([2,3,4])
print(a)
#[2 3 4]
#指定數據類型dtype
b = np.array([2,3,4],dtype = np.int)
print(b.dtype)
#int32
#三行四列全零數組,括號內為shape
c = np.zeros((3,4))
print(c)
‘‘‘
[[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]
‘‘‘
#全一數組
d = np.ones((3,4))
print(d)
‘‘‘
[[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]]
‘‘‘
#創建全空數組, 其實每個值都是接近於零的數
e = np.empty((3,4))
print(e)
#用 arange 創建連續數組,與range用法類似
f = np.arange(10,20,2)#10-19 的數據,2步長
print(f)
#[10 12 14 16 18]
#使用 reshape 改變數據的形狀
g = np.arange(12).reshape((3,4))
print(g)
‘‘‘
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
‘‘‘
#用 linspace 創建線段型數據
h = np.linspace(1,10,5)
print(h)
#[ 1. 3.25 5.5 7.75 10. ]
2.3 Numpy 基礎運算1
- 加減乘除
- 冪運算
- sum、max、min
- 按行或按列(axis)
import numpy as np
a = np.array([10,20,30,40])
b = np.arange(4)
c = a + b # [10, 21, 32, 43]
c = a - b # [10, 19, 28, 37]
c = b**2 # [0, 1, 4, 9]
c=10*np.sin(a) # [-5.44021111, 9.12945251, -9.88031624, 7.4511316 ]
print(b<3)# [ True, True, True, False]
a = np.array([[1,1],
[0,1]])
b = np.arange(4).reshape((2,2))
#對應元素相乘
c = a*b
‘‘‘
[[0 1]
[0 3]]
‘‘‘
#矩陣乘
c_dot = np.dot(a,b)
#c_dot = a.dot(b)
‘‘‘
[[2 4]
[2 3]]
‘‘‘
a=np.random.random((2,4))
print(a)
‘‘‘
[[ 0.35861795 0.4763303 0.62510912 0.64853572]
[ 0.53853158 0.70065019 0.17649662 0.99089602]]
‘‘‘
np.sum(a) # 4.4043622002745959
np.min(a) # 0.23651223533671784
np.max(a) # 0.90438450240606416
如果你需要對行或者列進行查找運算,就需要在上述代碼中為 axis 進行賦值。 當axis的值為0的時候,將會以列作為查找單元, 當axis的值為1的時候,將會以行作為查找單元。例:
print("sum =",np.sum(a,axis=1))
print("sum =",np.sum(a,axis=0))
2.4 Numpy 基礎運算2
- argmin/argmax:求矩陣最小/大值的索引
- mean/average:求均值
- median:中位數
- cumsum:累加
- diff:累差
- nonzero:將所有非零元素的行與列坐標分割開,重構成兩個分別關於行和列的矩陣
- sort:僅針對每一行進行從小到大排序操作
- 轉置 transpose/T
- clip:
clip(Array,Array_min,Array_max)
import numpy as np
A = np.arange(2,14).reshape((3,4))
print(A)
‘‘‘
[[ 2 3 4 5]
[ 6 7 8 9]
[10 11 12 13]]
‘‘‘
#均值
print(np.mean(A)) #7.5
print(A.mean()) #7.5
print(np.average(A)) #7.5
#累加
print(np.cumsum(A))
#[ 2 5 9 14 20 27 35 44 54 65 77 90]
#累差
print(np.diff(A))
‘‘‘
[[1 1 1]
[1 1 1]
[1 1 1]]
‘‘‘
print(np.nonzero(A))
#(array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64), array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))
#轉置
print(np.transpose(A))
print(A.T)
#clip
print(np.clip(A,5,9))
‘‘‘
[[5 5 5 5]
[6 7 8 9]
[9 9 9 9]]
‘‘‘
2.5 Numpy 索引
- 與數組類似,二維索引可用print(A[1][1])或者print(A[1,1])
- 可以使用分片操作,例A[1,1:3]
- flatten flat
import numpy as np
A = np.arange(3,15).reshape((3,4))
print(A.flatten())
# array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
for item in A.flat:
print(item)
# 3
# 4
……
# 14
flatten是一個展開性質的函數,將多維的矩陣進行展開成1行的數列。而flat
是一個叠代器,本身是一個object
屬性
2.6 Numpy array 合並
nump.vstack() 豎直方向/上下合並
import numpy as np
A = np.array([1,1,1])
B = np.array([2,2,2])
print(np.vstack((A,B))) # vertical stack
"""
[[1,1,1]
[2,2,2]]
"""
水平方向/左右合並
D = np.hstack((A,B)) # horizontal stack
print(D)
# [1,1,1,2,2,2]
nump.newaxis()新增一個維度
nump.concatenate():把合並多個矩陣
2.7 Numpy array 分割
axis = 1,表示行(x軸),切割行,分成多列
axis = 0,表示行(y軸),切割列,分成多行
import numpy as np
A = np.arange(12).reshape((3,4))
print(A)
print(np.split(A,2,axis = 1))
‘‘‘
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
‘‘‘
print(np.split(A,3,axis = 0))
#[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
#不等量分割
print(np.array_split(A, 3, axis=1))
‘‘‘
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2],
[ 6],
[10]]), array([[ 3],
[ 7],
[11]])]
‘‘‘
#vsplit與hsplit
print(np.vsplit(A, 3)) #等於 print(np.split(A, 3, axis=0))
# [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
print(np.hsplit(A, 2)) #等於 print(np.split(A, 2, axis=1))
"""
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
"""
2.8 Numpy copy & deep copy
同Python初學基礎
= 的賦值方式會帶有關聯性 ,copy() 的賦值方式沒有關聯性
Pandas 學習
3.1 Pandas 基本介紹
如果用 python 的列表和字典來作比較, 那麽可以說 Numpy 是列表形式的,沒有數值標簽,而 Pandas 就是字典形式。Pandas是基於Numpy構建的,讓Numpy為中心的應用變得更加簡單。
Series
>>> import pandas as pd
>>> s = pd.Series([1,2,3,np.nan,44,1])
>>> print(s)
0 1.0
1 2.0
2 3.0
3 NaN
4 44.0
5 1.0
dtype: float64
Series的字符串表現形式為:索引在左邊,值在右邊。由於我們沒有為數據指定索引。於是會自動創建一個0到N-1(N為長度)的整數型索引。
DataFrame
DataFrame是一個表格型的數據結構,它包含有一組有序的列,每列可以是不同的值類型(數值,字符串,布爾值等)。DataFrame
既有行索引也有列索引, 它可以被看做由Series
組成的大字典
>>> import pandas as pd
>>> import numpy as np
>>> s = pd.Series([1,2,3,np.nan,44,1])
>>> print(s)
0 1.0
1 2.0
2 3.0
3 NaN
4 44.0
5 1.0
dtype: float64
>>> dates = pd.date_range(‘20180101‘,periods=6)
>>> df = pd.DataFrame(np.random.randn(6,4),index = dates,columns=[‘a‘,‘b‘,‘c‘,‘d‘])
>>> df
a b c d
2018-01-01 -0.837319 0.250373 -1.218879 -0.018287
2018-01-02 0.094332 -0.546386 2.248513 -0.944102
2018-01-03 -0.805855 0.550253 0.552966 -1.704637
2018-01-04 -0.272391 0.150142 0.710317 0.397553
2018-01-05 -2.615182 -1.338799 -0.301048 0.732760
2018-01-06 0.281869 0.376154 0.092362 -1.588711
>>>
>>> df1 = pd.DataFrame(np.arange(12).reshape((3,4)))
>>> df1
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
#還可以用字典的方式生成
>>> df2 = pd.DataFrame({‘A‘ : 1.,
‘B‘ : pd.Timestamp(‘20130102‘),
‘C‘ : pd.Series(1,index=list(range(4)),dtype=‘float32‘),
‘D‘ : np.array([3] * 4,dtype=‘int32‘),
‘E‘ : pd.Categorical(["test","train","test","train"]),
‘F‘ : ‘foo‘})
>>> print(df2)
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
>>>
DataFrame 的一些簡單運用
>>> print(df[‘b‘])
2018-01-01 0.250373
2018-01-02 -0.546386
2018-01-03 0.550253
2018-01-04 0.150142
2018-01-05 -1.338799
2018-01-06 0.376154
Freq: D, Name: b, dtype: float64
>>> #查看數據中的類型
>>> print(df2.dtypes)
A float64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
>>> #查看對應行的序號
>>> print(df2.index)
Int64Index([0, 1, 2, 3], dtype=‘int64‘)
>>> #查看對應列
>>> print(df2.columns)
Index([‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘], dtype=‘object‘)
>>> #只查看所有df2的值
>>> print(df2.values)
[[1.0 Timestamp(‘2013-01-02 00:00:00‘) 1.0 3 ‘test‘ ‘foo‘]
[1.0 Timestamp(‘2013-01-02 00:00:00‘) 1.0 3 ‘train‘ ‘foo‘]
[1.0 Timestamp(‘2013-01-02 00:00:00‘) 1.0 3 ‘test‘ ‘foo‘]
[1.0 Timestamp(‘2013-01-02 00:00:00‘) 1.0 3 ‘train‘ ‘foo‘]]
>>> #數據總結
>>> df2.describe()
A C D
count 4.0 4.0 4.0
mean 1.0 1.0 3.0
std 0.0 0.0 0.0
min 1.0 1.0 3.0
25% 1.0 1.0 3.0
50% 1.0 1.0 3.0
75% 1.0 1.0 3.0
max 1.0 1.0 3.0
>>> #對數據的index排序
>>> print(df2.sort_index(axis=1,ascending=False))
F E D C B A
0 foo test 3 1.0 2013-01-02 1.0
1 foo train 3 1.0 2013-01-02 1.0
2 foo test 3 1.0 2013-01-02 1.0
3 foo train 3 1.0 2013-01-02 1.0
>>> #對數據值排序
>>> print(df2.sort_values(by=‘E‘))
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
2 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
3 1.0 2013-01-02 1.0 3 train foo
3.2 Pandas 選擇數據
簡單的篩選
import pandas as pd
import numpy as np
dates = pd.date_range(‘20130101‘,periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=[‘A‘,‘B‘,‘C‘,‘D‘])
print(df)
print(df[‘A‘]) #或print(df.A)
‘‘‘
2013-01-01 0
2013-01-02 4
2013-01-03 8
2013-01-04 12
2013-01-05 16
2013-01-06 20
Freq: D, Name: A, dtype: int32
‘‘‘
#跨越多行或多列
print(df[0:3]) #或print(df[‘20130102‘:‘20130104‘])
‘‘‘
A B C D
2013-01-01 0 1 2 3
2013-01-02 4 5 6 7
2013-01-03 8 9 10 11
‘‘‘
根據標簽loc
#select by label:loc
print(df.loc[‘20130102‘])
‘‘‘
A 4
B 5
C 6
D 7
Name: 2013-01-02 00:00:00, dtype: int32
‘‘‘
print(df.loc[:,[‘A‘,‘B‘]])
‘‘‘
A B
2013-01-01 0 1
2013-01-02 4 5
2013-01-03 8 9
2013-01-04 12 13
2013-01-05 16 17
2013-01-06 20 21
‘‘‘
根據序列iloc
#select by position:iloc
print(df.iloc[3,1])
#13
print(df.iloc[[1,3,5],1:3])
‘‘‘
B C
2013-01-02 5 6
2013-01-04 13 14
2013-01-06 21 22
‘‘‘
混合 ix
print(df.ix[:3,[‘A‘,‘C‘]])
"""
A C
2013-01-01 0 2
2013-01-02 4 6
2013-01-03 8 10
"""
通過判斷的篩選
print(df[df.A>8])
"""
A B C D
2013-01-04 12 13 14 15
2013-01-05 16 17 18 19
2013-01-06 20 21 22 23
"""
3.3 Pandas 設置值
可根據位置設置loc和iloc
例df.loc[2,2]=1111
df.loc[‘20130101‘,‘B‘]=2222
根據條件設置
df.B[df.A>4] = 0
"""
A B C D
2013-01-01 0 2222 2 3
2013-01-02 4 5 6 7
2013-01-03 8 0 1111 11
2013-01-04 12 0 14 15
2013-01-05 16 0 18 19
2013-01-06 20 0 22 23
"""
按行或列設置
df[‘F‘] = np.nan
"""
A B C D F
2013-01-01 0 2222 2 3 NaN
2013-01-02 4 5 6 7 NaN
2013-01-03 8 0 1111 11 NaN
2013-01-04 12 0 14 15 NaN
2013-01-05 16 0 18 19 NaN
2013-01-06 20 0 22 23 NaN
"""
或者加上Series序列,但是長度必須對齊
df[‘E‘] = pd.Series([1,2,3,4,5,6], index=pd.date_range(‘20130101‘,periods=6))
"""
A B C D F E
2013-01-01 0 2222 2 3 NaN 1
2013-01-02 4 5 6 7 NaN 2
2013-01-03 8 0 1111 11 NaN 3
2013-01-04 12 0 14 15 NaN 4
2013-01-05 16 0 18 19 NaN 5
2013-01-06 20 0 22 23 NaN 6
"""
3.4 Pandas 處理丟失數據
首先創建包含NaN的矩陣
dates = pd.date_range(‘20130101‘, periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates, columns=[‘A‘,‘B‘,‘C‘,‘D‘])
df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan
"""
A B C D
2013-01-01 0 NaN 2.0 3
2013-01-02 4 5.0 NaN 7
2013-01-03 8 9.0 10.0 11
2013-01-04 12 13.0 14.0 15
2013-01-05 16 17.0 18.0 19
2013-01-06 20 21.0 22.0 23
"""
dropna:去掉有NaN的行或列
print(df.dropna(axis=0,how=‘any‘)) # ‘any‘: 只要存在 NaN 就 drop 掉; ‘all‘: 必須全部是 NaN 才 drop
‘‘‘
A B C D
2013-01-03 8 9.0 10.0 11
2013-01-04 12 13.0 14.0 15
2013-01-05 16 17.0 18.0 19
2013-01-06 20 21.0 22.0 23
‘‘‘
fillna():將NaN的值用其他值代替
print(df.fillna(value=0))
‘‘‘
A B C D
2013-01-01 0 0.0 2.0 3
2013-01-02 4 5.0 0.0 7
2013-01-03 8 9.0 10.0 11
2013-01-04 12 13.0 14.0 15
2013-01-05 16 17.0 18.0 19
2013-01-06 20 21.0 22.0 23
‘‘‘
isnull():判斷是否有缺失數據NaN,為True表示缺失數據
print(df.isnull())
‘‘‘
A B C D
2013-01-01 False True False False
2013-01-02 False False True False
2013-01-03 False False False False
2013-01-04 False False False False
2013-01-05 False False False False
2013-01-06 False False False False
‘‘‘
print(np.any(df.isnull())==True)
#True
3.5 Pandas 導入導出
pandas可以讀取與存取的資料格式有很多種,像csv
、excel
、json
、html
與pickle
等…, 詳細請看官方說明文件
讀取csv
示範檔案下載 - student.csv
讀取csv
#讀取csv
data = pd.read_csv(‘student.csv‘)
#打印出data
print(data)
將資料存取成pickle
data.to_pickle(‘student.pickle‘)
3.6 Pandas 合並 concat
使用concat合並
import pandas as pd
import numpy as np
#定義資料集
df1 = pd.DataFrame(np.ones((3,4))*0, columns=[‘a‘,‘b‘,‘c‘,‘d‘])
df2 = pd.DataFrame(np.ones((3,4))*1, columns=[‘a‘,‘b‘,‘c‘,‘d‘])
df3 = pd.DataFrame(np.ones((3,4))*2, columns=[‘a‘,‘b‘,‘c‘,‘d‘])
#concat縱向合並
res = pd.concat([df1, df2, df3], axis=0) #函數默認axis=0。
#打印結果
print(res)
# a b c d
# 0 0.0 0.0 0.0 0.0
# 1 0.0 0.0 0.0 0.0
# 2 0.0 0.0 0.0 0.0
# 0 1.0 1.0 1.0 1.0
# 1 1.0 1.0 1.0 1.0
# 2 1.0 1.0 1.0 1.0
# 0 2.0 2.0 2.0 2.0
# 1 2.0 2.0 2.0 2.0
# 2 2.0 2.0 2.0 2.0
通過設置ignore_index可重置index
res = pd.concat([df1, df2, df3], axis=0, ignore_index=True)
#打印結果
print(res)
# a b c d
# 0 0.0 0.0 0.0 0.0
# 1 0.0 0.0 0.0 0.0
# 2 0.0 0.0 0.0 0.0
# 3 1.0 1.0 1.0 1.0
# 4 1.0 1.0 1.0 1.0
# 5 1.0 1.0 1.0 1.0
# 6 2.0 2.0 2.0 2.0
# 7 2.0 2.0 2.0 2.0
# 8 2.0 2.0 2.0 2.0
join合並
默認為outer值,縱向合並,有相同的column
上下合並在一起,其他獨自的column
個自成列,原本沒有值的位置皆以NaN
填充。
值為inner時,只有相同的column合並在一起,其余舍棄
res = pd.concat([df1, df2], axis=0, join=‘inner‘, ignore_index=True)
print(res)
# b c d
# 0 0.0 0.0 0.0
# 1 0.0 0.0 0.0
# 2 0.0 0.0 0.0
# 3 1.0 1.0 1.0
# 4 1.0 1.0 1.0
# 5 1.0 1.0 1.0
join_axes 依照axes合並
res = pd.concat([df1, df2], axis=1, join_axes=[df1.index])
#打印結果
print(res)
# a b c d b c d e
# 1 0.0 0.0 0.0 0.0 NaN NaN NaN NaN
# 2 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
# 3 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
append添加數據
只有縱向合並,沒有橫向合並
3.7 Pandas 合並 merge
pandas
中的merge
和concat
類似,但主要是用於兩組有key column的數據,統一索引的數據. 通常也被用在Database的處理當中
3.8 Pandas plot 出圖
主要講了ploy與scatter畫散點圖的用法,與matlab中的類似
為什麽用 Numpy 還是慢, 你用對了嗎?
Numpy&Pandas