Numpy&Pandas

Numpy & Pandas 簡介

此篇筆記參考來源爲《莫煩Pythonhtml

運算速度快:numpy 和 pandas 都是採用 C 語言編寫, pandas 又是基於 numpy, 是 numpy 的升級版本。python

消耗資源少:採用的是矩陣運算,會比 python 自帶的字典或者列表快好多git

Numpy 學習

2.1 numpy屬性

  • ndim:維度
  • shape:行數和列數
  • size:元素個數

舉例說明:github

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:建立數據全爲0
  • ones:建立數據全爲1
  • empty:建立數據接近0
  • arrange:按指定範圍建立數據
  • 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的時候,將會以行做爲查找單元。例:json

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]] """

水平方向/左右合併app

D = np.hstack((A,B))       # horizontal stack

print(D) # [1,1,1,2,2,2]

nump.newaxis()新增一個維度dom

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能夠讀取與存取的資料格式有不少種,像csvexceljsonhtmlpickle等…, 詳細請看官方說明文件

讀取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中的mergeconcat相似,但主要是用於兩組有key column的數據,統一索引的數據. 一般也被用在Database的處理當中

3.8 Pandas plot 出圖

主要講了ploy與scatter畫散點圖的用法,與matlab中的相似

 

爲何用 Numpy 仍是慢, 你用對了嗎?

本站公眾號
   歡迎關注本站公眾號,獲取更多信息