這一節繼續學習Numpy和Pandas。
一、numpy基礎運算二
透過上一節的學習,我們可以瞭解到一部分矩陣中元素的計算和查詢操作。然而在日常使用中,對應元素的索引也是非常重要的。依然,讓我們先從一個指令碼開始 :
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: np_yunsuan.py
@time: 18/8/26 23:37
"""
import numpy as np
A = np.arange(2, 14).reshape(3, 4)
# array([[ 2, 3, 4, 5]
# [ 6, 7, 8, 9]
# [10,11,12,13]])
print(np.argmin(A)) # 0
print(np.argmax(A)) # 11
常用方法
其中的 argmin()
和 argmax()
兩個函式分別對應著求矩陣中最小元素和最大元素的索引
。相應的,在矩陣的12個元素中,最小值即2,對應索引0,最大值為13,對應索引為11。
如果需要計算統計中的均值,可以利用下面的方式,將整個矩陣的均值求出來:
print(np.mean(A)) # 7.5
print(np.average(A)) # 7.5
仿照著前一節中dot()
的使用法則,mean()
函式還有另外一種寫法:
print(A.mean()) # 7.5
同樣的,我們可以寫出求解中位數的函式:
print(A.median()) # 7.5
另外,和matlab中的cumsum()
累加函式類似,Numpy中也具有cumsum()
函式,其用法如下:
print(np.cumsum(A))
# [2 5 9 14 20 27 35 44 54 65 77 90]
在cumsum()函式中:生成的每一項矩陣元素均是從原矩陣首項累加到對應項的元素之和。比如元素9,在cumsum()生成的矩陣中序號為3,即原矩陣中2,3,4三個元素的和。
下面我們介紹一下nonzero()
函式:
print(np.nonzero(A))
# (array([0,0,0,0,1,1,1,1,2,2,2,2]),array([0,1,2,3,0,1,2,3,0,1,2,3]))
這個函式將所有非零元素的行與列座標分割開,重構成兩個分別關於行和列的矩陣。
索引
一維索引
在元素列表或者陣列中,我們可以用如同a[2]一樣的表示方法,同樣的,在Numpy中也有相對應的表示方法:
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: np_index.py
@time: 18/8/28 00:49
"""
import numpy as np
A = np.arange(3, 11)
print(A) # [3 4 5 6 7 8 9 10]
print(A[3]) # 6
讓我們將矩陣轉換為二維的,此時進行同樣的操作:
A = np.arange(3, 11).reshape(2, 4)
"""
[[ 3 4 5 6]
[ 7 8 9 10]]
"""
print(A[1]) # [ 7 8 9 10]
實際上這時的A[1]對應的就是矩陣A中第二行(從0開始算第一行)的所有元素。
二維索引
如果你想要表示具體的單個元素,可以仿照上述的例子:
print(A[1][1]) # 8
此時對應的元素即A[1][1]
,在A中即橫縱座標都為1,第二行第二列的元素,即8(因為計數從0開始)。同樣的還有其他的表示方法:
print(A[1, 1]) # 8
在Python的 list 中,我們可以利用:
對一定範圍內的元素進行切片操作,在Numpy中我們依然可以給出相應的方法:
print(A[1, 1:3]) # [8 9]
這一表示形式即針對第二行中第2到第4列元素進行切片
輸出(不包含第4列)。
此時我們適當的利用for函式進行列印:
for row in A:
print(row)
"""
[ 3, 4, 5, 6]
[ 7, 8, 9, 10]
"""
此時它會逐行進行列印操作。如果想進行逐列列印,就需要稍稍變化一下:
for column in A.T:
print(column)
"""
[3 7]
[4 8]
[5 9]
[ 6 10]
"""
上述表示方法即對A進行轉置
,再將得到的矩陣逐行輸出即可得到原矩陣的逐列輸出。
最後依然說一些關於迭代輸出的問題:
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
屬性。
合併
-
np.vstack()
# vertical stack 上下合併 -
np.hstack()
# horizontal stack 左右合併 -
np.newaxis()
# 中轉置操作 -
np.concatenate()
# 多個合併
分割
建立資料
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: np_split.py
@time: 18/8/28 01:21
"""
import numpy as np
A = np.arange(12).reshape((3, 4))
print(A)
"""
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
"""
縱向分割
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]])]
錯誤的分割
範例的Array只有4列,只能等量對分,因此輸入以上程式程式碼後Python就會報錯。
print(np.split(A, 3, axis=1))
# ValueError: array split does not result in an equal division
為瞭解決這種情況, 我們會有下面這種方式.
不等量的分割
在機器學習時經常會需要將資料做不等量的分割,因此解決辦法為np.array_split()
print(np.array_split(A, 3, axis=1))
"""
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2],
[ 6],
[10]]), array([[ 3],
[ 7],
[11]])]
"""
成功將Array不等量分割!
其他的分割方式
在numpy裡還有np.vsplit()
與橫np.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]])]
"""
copy & deep copy
= 的賦值方式會帶有關聯性
import numpy as np
a = np.arange(4)
# array([0, 1, 2, 3])
b = a
c = a
d = b
改變a
的第一個值,b
、c
、d
的第一個值也會同時改變。
a[0] = 11
print(a)
# array([11, 1, 2, 3])
確認b、c、d是否與a相同。
b is a # True
c is a # True
d is a # True
同樣更改d
的值,a
、b
、c
也會改變。
d[1:3] = [22, 33] # array([11, 22, 33, 3])
print(a) # array([11, 22, 33, 3])
print(b) # array([11, 22, 33, 3])
print(c) # array([11, 22, 33, 3])
copy() 的賦值方式沒有關聯性
deep copy 為深賦值,重新建了一個地址
b = a.copy() # deep copy
print(b) # array([11, 22, 33, 3])
a[3] = 44
print(a) # array([11, 22, 33, 44])
print(b) # array([11, 22, 33, 3])
此時a
與b
已經沒有關聯。
二、pandas基礎
1、Numpy和Pandas有什麼不同
如果用 python 的列表和字典來作比較, 那麼可以說 Numpy 是列表形式的,沒有數值標籤,而 Pandas
就是字典形式
。Pandas是基於Numpy構建的,讓Numpy為中心的應用變得更加簡單。
要使用pandas,首先需要了解他主要兩個資料結構:Series
和DataFrame
。
Series
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: pd_new.py
@time: 18/8/30 00:22
"""
import pandas as pd
import numpy as np
s = pd.Series([1, 3, 6, np.nan, 44, 1])
print s
結果列印:
/Users/corwien/anaconda2/bin/python /Users/corwien/Code/python/baseLearn/pandas/pd_new.py
0 1.0
1 3.0
2 6.0
3 NaN
4 44.0
5 1.0
dtype: float64
Series
的字串表現形式為:索引在左邊,值在右邊。由於我們沒有為資料指定索引。於是會自動建立一個0到N-1(N為長度)的整數型索引。
DataFrame
dates = pd.date_range(`20180830`, periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=[`A`, `B`, `C`, `D`])
print(df)
"""
A B C D
2018-08-30 -0.838769 -0.366117 -0.501002 -0.418720
2018-08-31 0.062155 1.467156 1.995968 -0.460316
2018-09-01 0.553028 0.144778 1.944617 1.709808
2018-09-02 -0.116423 -1.134185 1.231541 0.862480
2018-09-03 -0.823016 0.491625 -1.448212 -0.921488
2018-09-04 -0.226200 0.353459 0.219459 0.635181
"""
DataFrame
是一個表格型的資料結構,它包含有一組有序的列,每列可以是不同的值型別(數值,字串,布林值等)。DataFrame既有行索引
也有列索引
, 它可以被看做由Series組成的大字典。
我們可以根據每一個不同的索引來挑選資料, 比如挑選 B
的元素:
DataFrame 的一些簡單運用
print(df[`b`])
"""
2018-08-30 0.391123
2018-08-31 -0.508613
2018-09-01 1.618023
2018-09-02 -1.168342
2018-09-03 -0.915434
2018-09-04 0.595129
Freq: D, Name: B, dtype: float64
"""
我們在建立一組沒有給定行標籤和列標籤的資料 df1
:
df1 = pd.DataFrame(np.arange(12).reshape((3,4)))
print(df1)
"""
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
"""
這樣,他就會採取預設的從0開始 index
. 還有一種生成 df
的方法, 如下 df2
:
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
"""
這種方法能對每一列的資料進行特殊對待. 如果想要檢視資料中的型別, 我們可以用 dtype
這個屬性:
print(df2.dtypes)
"""
df2.dtypes
A float64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
"""
同樣, 每種資料的名稱也能看到:
print(df2.columns)
# Index([`A`, `B`, `C`, `D`, `E`, `F`], dtype=`object`)
想知道資料的總結, 可以用 describe()
:
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
"""