Python模塊 - Numpy與Pandas


Numpy簡介

Numpy是高性能科學計算和數據分析的基礎包。它是pandas等其他各種工具的基礎。

Numpy的主要功能:

  • ndarray,一個多維數組結構,高效且節省空間
  • 無需循環對數組數據進行快速運算的數學函數
  • 線性代數、隨機數生成和博立葉變換功能

創建ndarray:np.array(array_list)

數組與列表的區別:

- 數組對象內的元素類型必須相同
- 數組大小不可修改

常用屬性

  • T 數組的轉置
  • size 數組元素的個數
  • ndim 數組的維數
  • shape 數組的維度大小(元祖形式)
  • dtype 數組元素的數據類型

創建array

np.zeros(10)	# 10個 0.的數組
np.ones(10)		# 10個的1.的數組

a = np.empty(100)		# 內存中存的值

np.arange(100)	# 快速創建100的數組
np.arange(15).reshape(3, 5)	# 創建二維數組
np.arange(2, 10, 0.3)
np.linspace(0, 50, 100)		# 0 ~ 50 平分成100份

np.eye(10)	# 線性代數

ndarray 批量運算

數組和標量之間的運算

a+1   1*3  1//a			a**0.5   a>5

同樣大小數組之間的運算

a+b a/b a**b a%b a==b

索引

  • 一位數組索引 a[5]

  • 多維數組索引

    • 列表式寫法 a[2][1]
    • 新式寫法 a[2, 1]

切片

  • 一位數組:a[5:8] a[4:] a[2:10]
  • 多維數組:a[1:2, 3:4] a[:, 3:5] a[:,1]
  • np數組的切片與列表切片的不同:數組切片時並不會自動復制(而是創建一個視圖),在切片數組上的修改會影響原數組
    • copy()方法可以創建數組的深拷貝

ndarray布爾型索引

問題:給一個數組,選出數組中所有大於5的數

答案:a[a>5]

原理

  • 數組與標量的運算:a>5會對a中的每一個元素進行判斷,返回一個布爾數組
  • 布爾型索引:將同樣大小的布爾數組傳進索引,會返回一個由所有True對應位置的元素的數組

例子:

# 1,給一個數組,選出數組中所有大於5的數
a = np.array([random.randint(1, 10) for _ in range(20)])
a[a>5]	# array([8, 6, 6, 7, 7, 6, 6])
# 2,給一個數組,選出數組中所有大於5的偶數
a = np.array([random.randint(1, 10) for _ in range(20)])
a[(a>5) & (a%2==0)]
# 3,給一個數組,選出數組中所有大於5的數和偶數
a = np.array([random.randint(1, 10) for _ in range(20)])
a[(a>5) | (a%2==0)]

ndarray花式索引

根據索引位置給出值

a = np.arange(20)
a[[1,4,5,6]]	# array([1, 4, 5, 6])
a = np.arange(20).reshape(4,5)	# array([[ 0,  1,  2,  3,  4],
                                        # [ 5,  6,  7,  8,  9],
                                        # [10, 11, 12, 13, 14],
                                        # [15, 16, 17, 18, 19]])

a[0, 2:5]	# array([7, 8, 9])
a[0, a[0]>2]
a[[1, 3], [1, 3]]	# 注意2個花式索引的取法,解析有點不一樣,獲取到的值是:array([ 6, 18])

# 如果就是想取6 8 16 18 可以使用下滿的方法
a[[1, 3],:][:,[1,3]]	# : 表示全切

Numpy 通用函數

通用函數:能同時對數組中所有元素進行運算的函數

補充知識:

int # 向零取整
round # 向零外取整,round到兩邊距離相等時取偶數值
math.floor # 向小取整(向左取整)(地板)
math.ceil	# 向大取整(向右取整)(天花)

常見通用函數:

一元函數: 對一維數組處理

np.abs(a) 	# 絕對值
np.sqrt(a)	# 開方
np.exp(a)
np.log(a) 
np.ceil(a) 	# 向大取整(向右取整)(天花)
np.floor(a) # 向小取整(向左取整)(地板)
np.rint(a) 	# 等價於 round
np.round(a)	# 向零外取整,round到兩邊距離相等時取偶數值 
np.trunc(a) # 向零取整
np.modf(a)	# 將小數和整數拆開
np.isnan(a) 	# 過濾nan
np.isinf(a)		# 過濾inf
np.cos(a)
np.sin(a)
np.tan(a)

例子

a = np.arange(-5.5,5)
np.abs(a)
x, y = np.modf(a)	# 將小數和整數拆開,x是小數,y是整數
# numpy過濾nan
a = np.arange(0,5)
b = a/a					# array([nan,  1.,  1.,  1.,  1.])
b[~np.isnan(b)]	# ~ 是取反
# numpy過濾inf
a=np.array([3,4,5,6])
b=np.array([2,0,3,0])
c = a/b
c[c!=np.inf]		# 過濾inf
c[~np.isinf(c)]	# 過濾inf

二元函數: 對二維數組處理

np.add(a,b)					# a數組 + b數組   
np.subtract(a,b)		# a-b  一般不用調函數,直接對數組相加就好
np.multiply(a,b)
np.divide(a,b)
np.power(a,b)
np.mod(a,b)
np.maximum(a,b)		# 兩個數組中的最大
np.minimum(a,b)		# 兩個數組中的最小

Numpy 數學和統計方法

sum 	# 求和
mean	# 求平均值
std		# 求標准差
var		# 求方差

min		# 求最小值
max		# 求最大值
argmin	# 求最小值索引
argmax	# 求最大值索引

# 求方差
1 2 3 4 5
mean:3
((1-3)**2+(2-3)**2+(3-3)**2+(4-3)**2+(5-3)**2)/5

# 方差表示你這組數據的離散程度

標准差 = sqrt(方差)

# 差不多60%的數據分布在這區間
a.mean()+a.std()
a.mean()-a.std()

# 差不多80%的數據分布在這區間
a.mean()+2*a.std()
a.mean()-2*a.std()

Numpy 隨機數生成

隨機數函數在np.random子包內

np.random.rand			給定形狀產生隨機數組(0 ~ 1之間)
np.random.randint		給定**長度**產生隨機整數
np.random.choice		給定形狀產生隨機選擇
np.random.shuffle		與random.shuffle相同
np.random.uniform		給定形狀產生隨機數組

例子

np.random.randint(0, 10, 10)	# 生成一個長度10的隨機數組
np.random.rand(5)
np.random.choice([1,2,3,4,5], (2,3))
np.random.uniform(2,5, (3,4))

補充 - 浮點數特殊值

  • nan (Not a Number): 不等於任何浮點數(nan != nan)
  • inf(infinity):比任何浮點數都大
  • Numpy中創建特殊值:np.nan np.inf
  • 在數據分析中,nan常被用作表示數據缺失值

Pandas 數據分析

pandas簡介

pandas是一個強大的Python數據分析的工具包,是基於NumPy構建的。

pandas的主要功能:

  • 具備對其功能的數據結構DataFrame、Series
  • 集成時間序列功能
  • 提供豐富的數學運算和操作
  • 靈活處理缺失數據

安裝方法pip install pandas

引用方法import pandas as pd

Series 一維數組對象

Series是一種類似於一維數組的對象,由一組數據和一組與之相關相關的數據標簽(索引)組成。

創建方式

pd.Series([4, 5, -5, 3])
pd.Series([4, 5, -5, 3], index=['a', 'b', 'c', 'd'])
pd.Series({'a': 1, 'b': 2, 'c': 3})
pd.Series(0, index=['a', 'b', 'c'])

合並兩個Series

sr = sr1.append(sr2).sort_index() # 方式二 (0,死叉) (1,金叉)

獲取值數組和索引數組:values屬性和index屬性

Series比較像列表(數組)和字典的結合體

Series 使用特性

Series支持array的(下標)特性:

  • ndarray創建Series: Series(arr)
  • 與標量運算:sr * 2
  • 兩個Series運算:sr1+sr2
  • 索引:sr[0] [sr[[1,2,4]]]
  • 切片:sr[0:2]
  • 通用函數:np.abs(sr)
  • 布爾值過濾:sr[sr>0]

Series支持字典的特性(標簽)

  • 從字典創建Series:Series(dic)
  • in運算:'a' in sr
  • 鍵索引:sr['a'] sr[['a', 'b', 'd']]
sr.index
sr.values
sr.index[0]
sr[[1, 3]]
sr[['a', 'd']]
sr['a': 's']	# 通過標簽切片,前包后也包

Series 整數索引

pandas Series對象的整數索引往往會使新手抓狂。

例如

sr = pd.Series(np.arange(4))
sr[-1]	# 會報錯

如果索引是整數類型,則根據整數進行下標獲取值時總是面向標簽的。

解決辦法:loc屬性(將索引解釋為標簽)和iloc屬性(將索引解釋為下標)

sr2.loc[10]		# 根據標簽索引
sr2.iloc[10]	# 根據下標索引

sr2.iloc[-1]
sr2.iloc[3:6]
sr2.iloc[[2, 3, 7]]

Series 數據對齊

兩個series數組對象,將會根據索引對齊后再相加

sr1 = pd.Series([11,23,34], index=['c','a','d'])
sr2 = pd.Series([11,20,10], index=['d','c','a'])
sr1+sr2		# 將會按照index對齊之后進行相加
sr1 = pd.Series([11,23,34], index=['c','a','d'])
sr2 = pd.Series([11,20,10,21], index=['d','c','a','b'])
sr1+sr2		# 出現缺省值,b 將會用 NaN 代替
sr1 = pd.Series([11,23,34], index=['b','a','d'])
sr2 = pd.Series([11,20,10], index=['d','c','a'])
sr1+sr2		# b     NaN			c     NaN
sr1 = pd.Series([11,23,34], index=['b','a','d'])
sr2 = pd.Series([11,20,10], index=['d','c','a'])
# 如何使結果在索引`b`處的值為11,在索引`c`處的值為20
# 靈活的算術方法:add sub div mul
sr1.add(sr2, fill_value=0)	# sr1 + sr2 , 有NaN就用0代替

Series 缺失值的處理

sr.isnull()		# NaN 返回 True
sr.notnull()	# not NaN 返回 True
# 丟掉
sr = sr[sr.notnull()]
sr = sr.dropna()
# 填充成其他值
sr = sr.fillna(0)					# 使用0填充
sr = sr.fillna(sr.mean())	# 使用平均值填充

DataFrame的創建方式

dataframe的列得是同一個類型

DataFrame是一個表格型的數據結構,含有一組有序的列。DataFrame可以被看作是由Series組成的字典,並且共用一個索引。

創建方式

# 方式一
pd.DataFrame({'one': [1,2,3], 'two': [4,5,6]})
pd.DataFrame({'one': [1,2,3], 'two': [4,5,6]}, index=['a','b','c'])
# 方式二
pd.DataFrame({'one':pd.Series([1,2,3],index=['a','b','c']), 'two':pd.Series([1,2,3,4], index=['b','a','c','d'])})

csv文件讀取與寫入

df.to_csv('test2.csv')
pd.read_csv('test2.csv')

DataFrame 常用屬性

index		行索引
T				轉置
columns		獲取列索引
values		獲取值數組 (二維數組)
describe()		獲取快速統計

DataFrame 索引和切片

DataFrame是一個二維數據類型,所以有行索引和列索引。

DataFrame同樣可以銅鼓標簽和位置兩種方法進行索引和切片

loc屬性和iloc屬性

  • 使用方法:逗號隔開,前面是行索引,后面是列索引
  • 行/列索引部分可以是常規索引、切片、布爾值索引、花式索引任意搭配

loc會將行解釋為索引標簽iloc會將行解釋為其索引下標

df['one']['a']			# one是列索引,a是行索引
df.loc['a', 'one']	# 推薦這種,a 是 行索引,one是列索引
df.loc['a',:]				# 切片 a 這一行數據

df.loc[['a','c'],:]
df.loc[['a','c'],'two']		# 任意搭配

DataFrame 數據對齊與缺省數據

DataFrame對象在運算時,同樣會進行數據對齊,其行索引和列索引分別對齊。

DataFrame處理缺省數據的相關方法:

dropna(axis=0,how='any',...)		# axis=0按行刪;axis=1按列刪。how='any' 出現一個就刪,how='all'都出現才刪。
fillna()		# 填充
isnull()
notnull()
df.dropna(how='all')	# 都出現才刪除	默認是 any
df2.dropna(axis=1)		# 按列刪	默認是0

Pandas 其他常用方法

mean(axis=0, skipna=False)		對列(行)求平均值
sum(axis=1)										對列(行)求平均值
sort_index(axio,...,ascending)	對列(行)索引排序
sort_values(by, axis, ascending)	 按某一列(行)的值排序,注意:有nan的不參與排序 放到最后顯示

# Numpy的通用函數同樣適用於pandas

例子

f.sort_values(by='two')	# 按two列排序
df.sort_values(by='two', ascending=False)	# 按two降序排序
df.sort_values(by=1, ascending=False, axis=1)	# 按1這一行降序排序

df.sort_index()		# 按行索引排序
df.sort_index(ascending=False)	# 按行索引降序排序
df.sort_index(ascending=False, axis=1)	# 按列索引降序排序

Pandas 時間對象

時間序列類型:

  • 時間戳:特定時刻
  • 固定日期:如2017年7月
  • 時間間隔:起始時間-結束時間

Python標准庫處理時間對象datetime

靈活處理時間對象dateutil dateutil.parser.parse()

成組處理事件對象pandas pd.to_datetime()

datetime.datetime.strptime('2010-08-21', '%Y-%m-%d')
import dateutil
dateutil.parser.parse('2001-01-01')
dateutil.parser.parse('200101/01')
dateutil.parser.parse('2001/01/01')
dateutil.parser.parse('01/01/2020')
pd.to_datetime(['2019-01-01','2010/Feb/02'])

Pandas 時間對象處理

產生時間對象數組 date_range

start 開始時間
end		結束時間
period	時間長度
freq		時間頻率,默認為'D', 可選H(our), W(eek), B(usiness),S(emi-)M(onth),(min)T(es), S(econd), A(year), ...
pd.date_range('2010-01-01','2010-5-1')
pd.date_range('2010-01-01',periods=60)
pd.date_range?
pd.date_range('2010-01-01',periods=60,freq='H')
pd.date_range('2010-01-01',periods=60,freq='W')
pd.date_range('2010-01-01',periods=60,freq='W-MON')
pf = pd.date_range('2010-01-01',periods=60,freq='B')
pd.date_range('2010-01-01',periods=60,freq='1h20min')
df[0].to_pydatetime()		# 轉換成Python的datetime類型

將索引轉換為時間列

df['date'] = pd.to_datetime(df['date'])
df.set_index("date", inplace=True)
# df.set_index('date',drop=True)

Pandas 時間序列

時間序列就是以時間對象為索引的Series或DataFrame

datetime對象作為索引時是存儲在DatetimeIndex對象中的

時間序列特殊功能:

  • 傳入“年”或“年月”作為切片方式
  • 傳入日期范圍作為切片方式
  • 豐富的函數支持:resample(), truncate() ....
sr = pd.Series(np.arange(1000), index=pd.date_range('2017-1-1', periods=1000))
sr['2017-3']
sr['2017-4']
sr['2017']
sr['2017':'2018-3']
sr['2017-12-24':'2018-2-1']
sr.resample('W').sum()	# 按周求和
sr.resample('m').sum()
sr.resample('m').mean()
sr.resample('M').first()	# 每個月第一天數據
sr.truncate(before='2018-2-3')	# 切掉掉前面的,因為有時間切片了,所以不推薦這個方法
sr.truncate(after='2018-2-3')

Pandas 文件處理

數據文件常用格式:csv(以某間隔符分割字符)

pandas讀取文件:從文件名、URL、文件對象中加載數據

  • read_csv 默認分隔符為逗號
  • read_table 默認分隔符為制表符

read_csv read_table 函數主要參數

sep			指定分隔符,可用正則表達式,如'\s+', 不指定則默認是 `,`
header=None			指定文件無列名
names						指定列名
index_col				指定某列作為索引
skip_row				指定跳過某些行
na_values				指定某些字符串表示缺失值(將某些奇怪字符串解析成NaN)
parse_dates			指定某些列是否被解析為日期,類型為布爾型或列表

例子

# 常用
df = pd.read_csv('zn2006SHFE2020.csv', index_col='datetime', parse_dates=['datetime'])[['open','high','low','close']]
pd.read_csv('zn2006.csv')
pd.read_csv('zn2006.csv', index_col=0)		# 指定第0列為索引
pd.read_csv('zn2006.csv', index_col='datetime')		# 指定`datetime`列為索引
pd.read_csv('zn2006.csv', index_col='datetime', parse_dates=True)
pd.read_csv('zn2006.csv', index_col='datetime', parse_dates=['datetime'])
pd.read_csv('zn2006.csv', header=None)
pd.read_csv('zn2006.csv', header=None, names=list('qwertyuiopasdfg'))
pd.read_csv('zn2006.csv', header=None, skiprows=[2,3,4])
pd.read_csv('zn2006.csv', na_values=['None'])		# 將None替換為NaN

寫入到CSV文件:to_csv函數

寫入文件函數的主要參數:

sep			指定文件分隔符
na_rep	指定缺失值轉換的字符串,默認為空字符串
header=False		不輸出列名一行
index=False			不輸出行索引一行
cols						指定輸出的列,傳入列表
df.to_csv('test.csv', header=False, index=False, na_rep='null')
df.to_csv('test.csv', header=False, index=False, na_rep='null',columns=['open','high','low','close'])
df.to_html('test.html')
pd.read_excel('test.xlsx')

pandas支持的其他文件類型

  • json
  • xml
  • html
  • 數據庫
  • pickle
  • excel

補充

rolling函數

可以取前10的窗口

df['pre_high'] = df['high'].rolling(10).max()

shift平移函數

通過shift函數里面的值來控制向前還是向后偏移, 缺少的值會填充NaN,groupby函數里的參數控制基於什么字段進行shift.

注意-1 是向前前移

df16['pre_close'] = df16['close'].shift(1)	# 向后偏移
temp['value_shift'] = temp.groupby('id')['value'].shift(1);temp
Out[180]: 
   id  value  value_shift
0   1      1          NaN
1   1      2          1.0
2   1      3          2.0
3   2      4          NaN
4   2      5          4.0
5   3      6          NaN

temp['value_shift_1'] = temp.groupby('id')['value'].shift(-1);temp
Out[181]: 
   id  value  value_shift  value_shift_1
0   1      1          NaN            2.0
1   1      2          1.0            3.0
2   1      3          2.0            NaN
3   2      4          NaN            5.0
4   2      5          4.0            NaN
5   3      6          NaN            NaN

通過shift函數里面的值來控制向前還是向后偏移, 缺少的值會填充NaN.

groupby函數里的參數控制基於什么字段進行shift.

補充函數

series.describe()		# 總結數據分布情況
np.sign(<series/array>)		# sign()是Python的Numpy中的取數字符號(數字前的正負號)的函數。(大於0,返回1) ;(等於0,返回0);(小於0,返回-1)
Series.value_counts()			# 統計值的出現次數
series.cumsum()						# 累加之前的數據
series.cumprod()					# 累乘之前的數據
series.pct_change()				# 表示當前元素與先前元素的相差百分比,當然指定periods=n,表示當前元素與先前第n 個元素的相差百分比。可以用來算當天較上一天的return(收益)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM