進(jìn)階法寶!掌握這些 NumPy & Pandas 方法,快速提升數(shù)據(jù)處理效率
Pandas 是基于NumPy 的一種工具,該工具是為解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。pandas 納入了大量庫和一些標(biāo)準(zhǔn)的數(shù)據(jù)模型,提供了高效地操作大型數(shù)據(jù)集所需的工具。pandas提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。你很快就會發(fā)現(xiàn),它是使python成為強(qiáng)大而高效的數(shù)據(jù)分析環(huán)境的重要因素之一。
NumPy
NumPy庫是Python中用于科學(xué)計(jì)算的核心庫。它提供了一個(gè)高性能的多維數(shù)組對象,以及用于處理這些數(shù)組的工具。

導(dǎo)入Numpy
import numpy as np
創(chuàng)建 Arrays
>>> a = np.array([1,2,3])
>>> b = np.array([(1.5,2,3), (4,5,6)], dtype = float)
>>> c = np.array([[(1.5,2,3), (4,5,6)], [(3,2,1), (4,5,6)]],dtype = float)
# 創(chuàng)建一個(gè)由0組成的數(shù)組
>>> np.zeros((3,4))
# 創(chuàng)建一個(gè)1的數(shù)組
>>> np.ones((2,3,4),dtype=np.int16)
# 創(chuàng)建一個(gè)等距值數(shù)組(步長值)
>>> d = np.arange(10,25,5)
# 創(chuàng)建一個(gè)等距值數(shù)組(樣本數(shù))
>>> np.linspace(0,2,9)
# 創(chuàng)建一個(gè)常量數(shù)組
>>> e = np.full((2,2),7)
# 創(chuàng)建一個(gè)2X2單位矩陣
>>> f = np.eye(2)
# 創(chuàng)建一個(gè)隨機(jī)值的數(shù)組
>>> np.random.random((2,2))
# 創(chuàng)建一個(gè)空數(shù)組
>>> np.empty((3,2))
輸入與輸出
從磁盤上導(dǎo)入與存儲
>>> np.save('my_array', a)
>>> np.savez('array.npz', a, b)
>>> np.load('my_array.npy')
導(dǎo)入與存儲文本文件
>>> np.loadtxt("myfile.txt")
>>> np.genfromtxt("my_file.csv", delimiter=',')
>>> np.savetxt("myarray.txt", a, delimiter=" ")
數(shù)據(jù)類型
>>> np.int64 # 有符號64位整數(shù)類型
>>> np.float32 # 標(biāo)準(zhǔn)雙精度浮點(diǎn)數(shù)
>>> np.complex # 由128個(gè)浮點(diǎn)數(shù)表示的復(fù)數(shù)
>>> np.bool # 布爾類型,存儲TRUE和FALSE值
>>> np.object # Python對象類型
>>> np.string_ # 固定長度的字符串類型
>>> np.unicode_# 固定長度的unicode類型
查看數(shù)組
>>> a.shape # 陣列尺寸
>>> len(a) # 數(shù)組的長度
>>> b.ndim # 陣列維數(shù)
>>> e.size # 數(shù)組元素?cái)?shù)
>>> b.dtype # 數(shù)組元素的數(shù)據(jù)類型
>>> b.dtype.name # 數(shù)據(jù)類型名稱
>>> b.astype(int) # 將數(shù)組轉(zhuǎn)換為不同類型
獲取幫助
>>> np.info(np.ndarray.dtype)
Array 算術(shù)運(yùn)算
>>> g = a - b # 減法
array([[-0.5, 0. , 0. ],
[-3. , -3. , -3. ]])
>>> np.subtract(a,b) # 減法
>>> b + a # 加法
array([[ 2.5, 4. , 6. ],
[ 5. , 7. , 9. ]])
>>> np.add(b,a) # 加法
>>> a / b # 除法
array([[ 0.66666667, 1. , 1. ],
0.25 , 0.4, 0.5])
>>> a * b # 乘法
array([[ 1.5, 4. , 9. ],
[ 4. , 10. , 18. ]])
>>> np.multiply(a,b) # 乘法
>>> np.divide(a,b) # 除法
>>> np.exp(b) # 求冪
>>> np.sqrt(b) # 平方根
>>> np.sin(a) # 輸出一個(gè)數(shù)組的正弦值
>>> np.cos(b) # 輸出一個(gè)數(shù)組的余弦值
>>> np.log(a) # 輸出一個(gè)數(shù)組的自然對數(shù)
>>> e.dot(f) # 點(diǎn)積
array([[ 7., 7.], [ 7., 7.]])
比較大小
>>> a == b # 數(shù)組元素比較
array([[False, True, True],
[False, False, False]], dtype=bool)
>>> a < 2 # 數(shù)組元素比較
array([True, False, False], dtype=bool)
>>> np.array_equal(a, b) # 數(shù)組比較
統(tǒng)計(jì)函數(shù)
>>> a.sum() # 數(shù)組求和
>>> a.min() # 數(shù)組最小值
>>> b.max(axis=0) # 數(shù)組行最大值
>>> b.cumsum(axis=1) # 元素均值的累積和
>>> a.mean() # 中位數(shù)
>>> b.median() # 相關(guān)系數(shù)
>>> a.corrcoef() # 相關(guān)系數(shù)
>>> np.std(b) # 標(biāo)準(zhǔn)偏差
數(shù)組拷貝
>>> h = a.view() # 使用相同的數(shù)據(jù)創(chuàng)建數(shù)組的視圖
>>> np.copy(a) # 創(chuàng)建數(shù)組的副本
>>> h = a.copy() # 創(chuàng)建數(shù)組的深層副本
數(shù)組排序
>>> a.sort() # 排序數(shù)組
>>> c.sort(axis=0) # 對數(shù)組橫軸的元素進(jìn)行排序
切片與索引
獲取單個(gè)元素
>>> a[2] # 選擇第二個(gè)索引處的元素
3
>>> b[1,2] # 選擇第1行第2列的元素(相當(dāng)于b[1][2])
1.5 2 3 6.0 456
獲取子集
>>> a[0:2] # 選擇索引0和1的項(xiàng)
array([1, 2])
>>> b[0:2,1] # 選擇第1列中第0行和第1行中的項(xiàng)目
array([ 2., 5.])
>>> b[:1] # 選擇第0行中的所有項(xiàng)目,等價(jià)于b[0:1,:]
array([[1.5, 2., 3.]])
>>> c[1,...] # 與[1,:,:]一樣
array([[[3., 2., 1.],
[4., 5., 6.]]])
>>> a[ : :-1] # 逆轉(zhuǎn)了數(shù)組
array([3, 2, 1])
布爾索引
>>> a[a<2] # 從小于2的a中選擇元素
array([1])
花俏的索引
>>> b[[1, 0, 1, 0],[0, 1, 2, 0]] # 選擇元素(1,0),(0,1),(1,2) 和 (0,0)
array([4.,2.,6.,1.5])
>>> b[[1, 0, 1, 0]][:,[0,1,2,0]] # 選擇矩陣的行和列的子集
array([[4.,5.,6.,4.],
[1.5,2.,3.,1.5],
[4.,5.,6.,4.],
[1.5,2.,3.,1.5]])
數(shù)組操作
轉(zhuǎn)置數(shù)組
>>> i = np.transpose(b) # 交換數(shù)組維度
>>> i.T
改變數(shù)組形狀
>>> b.ravel() # 將數(shù)組壓平
>>> g.reshape(3,-2) # 不會改變數(shù)據(jù)
添加和刪除數(shù)組元素
>>> h.resize((2,6)) # 返回一個(gè)具有形狀(2,6)的新數(shù)組
>>> np.append(h,g) # 向數(shù)組添加項(xiàng)
>>> np.insert(a, 1, 5) # 在數(shù)組中插入項(xiàng)
>>> np.delete(a,[1]) # 從數(shù)組中刪除項(xiàng)
合并數(shù)組
>>> np.concatenate((a,d),axis=0)# 連接數(shù)組
array([ 1, 2, 3, 10, 15, 20])
>>> np.vstack((a,b)) # 垂直(行)堆疊陣列
array([[ 1. , 2. , 3. ],
[ 1.5, 2. , 3. ],
[ 4. , 5. , 6. ]])
>>> np.r_[e,f] # 垂直(行)堆疊陣列
>>> np.hstack((e,f)) # 水平(列)堆疊陣列
array([[ 7., 7., 1., 0.],
[ 7., 7., 0., 1.]])
>>> np.column_stack((a,d))# 創(chuàng)建堆疊的列陣列
array([[ 1, 10],
[ 2, 15],
[ 3, 20]])
>>> np.c_[a,d] # 創(chuàng)建堆疊的列陣列
分割數(shù)組
>>> np.hsplit(a,3) # 在第3個(gè)索引處水平分割數(shù)組
[array([1]),array([2]),array([3])]
>>> np.vsplit(c,2) # 在第二個(gè)索引處垂直分割數(shù)組
[array([[[ 1.5, 2. , 1. ],
[ 4. , 5. , 6. ]]]),
array([[[ 3., 2., 3.],
[ 4., 5., 6.]]])]
Pandas
Pandas庫建立在NumPy上,并為Python編程語言提供了易于使用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具。
導(dǎo)入Pandas
>>> import pandas as pd
Series
>>> s = pd.Series([3,5,-7,9], index=['A', 'B', 'C', 'D'])

DataFrame
>>> data = {'Country': ['Belgium', 'India', 'Brazil'],
'Capital': ['Brussels', 'New Delhi', 'Brasília'],
'Population': [11190846, 1303171035, 207847528]}
>>> df = pd.DataFrame(data,
columns=['Country', 'Capital', 'Population'])

獲取幫助信息
>>> help(pd.Series.loc)
切片與索引
獲取元素
>>> s['b'] # 獲取一個(gè)元素
-5
>>> df[1:] # 獲取DataFrame子表
Country Capital Population
1 India New Delhi 1303171035
2 Brazil Brasi?lia 207847528
布爾索引
# 通過位置
>>> df.iloc[[0],[0]] # 按行和列選擇單個(gè)值
'Belgium'
>>> df.iat([0],[0])
'Belgium'
# 通過標(biāo)簽
>>> df.loc[[0], ['Country']] # 通過行和列標(biāo)簽選擇單個(gè)值
'Belgium'
>>> df.at([0], ['Country'])
'Belgium'
# 通過標(biāo)簽或位置
>>> df.ix[2] # 選擇行子集中的單行
Country Brazil
Capital Brasília
Population 207847528
>>> df.ix[:,'Capital'] # 選擇列子集中的單列
0 Brussels
1 New Delhi
2 Brasília
>>> df.ix[1,'Capital'] # 選擇行和列
'New Delhi'
# 布爾索引
>>> s[~(s > 1)] # 選擇Series s的值不大于1的子集
>>> s[(s < -1) | (s > 2)] # 選擇Seriess的值是<-1或>2 的子集
>>> df[df['Population']>1200000000] # 使用過濾器來調(diào)整數(shù)據(jù)框
# 設(shè)置
>>> s['a'] = 6 # 將Series s的索引a設(shè)為6
Dropping
>>> s.drop(['a', 'c']) # 從行刪除值 (axis=0)
>>> df.drop('Country', axis=1) # 從列刪除值
Sort & Rank
>>> df.sort_index() # 按軸上的標(biāo)簽排序
>>> df.sort_values(by='Country') # 按軸上的值排序
>>> df.rank()
檢索Series / DataFrame上的信息
基礎(chǔ)信息
>>> df.shape # (行、列)
>>> df.index # 描述指數(shù)
>>> df.columns # 描述DataFrame列
>>> df.info() # DataFrame信息
>>> df.count() # 非空值的個(gè)數(shù)
統(tǒng)計(jì)信息
>>> df.sum() # 值的總和
>>> df.cumsum() # 值的累積和
>>> df.min()/df.max() # 最小/最大值
>>> df.idxmin()/df.idxmax() # 最小/最大索引值
>>> df.describe()# 摘要統(tǒng)計(jì)信息
>>> df.mean() # 值的意思
>>> df.median() # 中位數(shù)的值
Apply 函數(shù)
>>> f = lambda x: x*2
>>> df.apply(f) # Apply函數(shù)
>>> df.applymap(f) # Apply每個(gè)元素
數(shù)據(jù)一致性
內(nèi)部數(shù)據(jù)一致
在不重疊的索引中引入NA值
>>> s3 = pd.Series([7, -2, 3], index=['a', 'c', 'd'])
>>> s + s3
a 10.0
b NaN
c 5.0
d 7.0
填充方法的算術(shù)運(yùn)算
你也可以在fill方法的幫助做內(nèi)部數(shù)據(jù)一致
>>> s.add(s3, fill_value=0)
a 10.0
b -5.0
c 5.0
d 7.0
>>> s.sub(s3, fill_value=2)
>>> s.div(s3, fill_value=4)
>>> s.mul(s3, fill_value=3)
輸入與輸出
讀取與寫入到CSV
>>> pd.read_csv('file.csv', header=None, nrows=5)
>>> df.to_csv('myDataFrame.csv')
讀取與寫入到Excel
>>> pd.read_excel('file.xlsx')
>>> pd.to_excel('dir/myDataFrame.xlsx', sheet_name='Sheet1')
# 從同一個(gè)文件中讀取多個(gè)工作表
>>> xlsx = pd.ExcelFile('file.xls')
>>> df = pd.read_excel(xlsx, 'Sheet1')
讀取與寫入到SQL 查詢或數(shù)據(jù)庫表中
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:')
>>> pd.read_sql("SELECT * FROM my_table;", engine)
>>> pd.read_sql_table('my_table', engine)
>>> pd.read_sql_query("SELECT * FROM my_table;", engine)
>>> pd.to_sql('myDf', engine)
read_sql()是read_sql_table()和read_sql_query()到一個(gè)便捷的封裝。
數(shù)據(jù)透視Pivot
# 將行展開成列
>>> df3= df2.pivot(index='Date',
columns='Type',
values='Value')

數(shù)據(jù)透視表Pivot_table
# 將行展開成列
>>> df4 = pd.pivot_table(df2,
values='Value',
index='Date',
columns=['Type'])
堆疊 stack/unstack
stack和unstack是python進(jìn)行層次化索引的重要操作。
Stack: 將數(shù)據(jù)的列索引轉(zhuǎn)換為行索引(列索引可以簡單理解為列名) Unstack: 將數(shù)據(jù)的行索引轉(zhuǎn)換為列索引
>>> stacked = df5.stack()
>>> stacked.unstack()

pandas.melt(frame,
id_vars=None,
value_vars=None,
var_name=None,
value_name='value',
col_level=None)
frame:
要處理的數(shù)據(jù)集。id_vars:
不需要被轉(zhuǎn)換的列名。value_vars:
需要轉(zhuǎn)換的列名,如果剩下的列全部都要轉(zhuǎn)換,就不用寫了。var_name和value_name:
是自定義設(shè)置對應(yīng)的列名。col_level :
如果列是MultiIndex,則使用此級別。
寬數(shù)據(jù)--->>長數(shù)據(jù),有點(diǎn)像用excel做透視跟逆透視的過程。
>>> pd.melt(df2,
id_vars=["Date"],
value_vars=["Type", "Value"],
value_name="Observations")

迭代
# (Column-index, Series) 對
>>> df.iteritems()
# (Row-index, Series) 對
>>> df.iterrows()
高級索引
# 按條件選擇
>>> df3.loc[:,(df3>1).any()] # 選擇只要有變量大于1的列
>>> df3.loc[:,(df3>1).all()] # 選擇所有變量大于1的列
>>> df3.loc[:,df3.isnull().any()] # 選擇帶NaN的列
>>> df3.loc[:,df3.notnull().all()] # 選擇不帶NaN的列
# 用isin索引選擇
>>> df[(df.Country.isin(df2.Type))] # 找到相同的元素
>>> df3.filter(items=["a","b"]) # 過濾值
>>> df.select(lambda x: not x%5) # 選擇特定的元素
# Where
>>> s.where(s > 0) # 滿足條件的子集的數(shù)據(jù)
# Query
>>> df6.query('second > first') # 查詢DataFrame
設(shè)置與重置索引
>>> df.set_index('Country') # 設(shè)置索引
>>> df4 = df.reset_index() # 重置索引
# DataFrame重命名
>>> df = df.rename(index=str,columns={"Country":"cntry",
"Capital":"cptl",
"Population":"ppltn"})
重建索引
>>> s2 = s.reindex(['a','c','d','e','b'])
向前填充
>> df.reindex(range(4),
method='ffill')
Country Capital Population
0 Belgium Brussels 11190846
1 India New Delhi 1303171035
2 Brazil Brasília 207847528
3 Brazil Brasília 207847528
向后填充
>>> s3 = s.reindex(range(5),
method='ffill')
0 3
1 3
2 3
3 3
4 3
多重索引
>>> arrays = [np.array([1,2,3]),
np.array([5,4,3])]
>>> df5 = pd.DataFrame(np.random.rand(3, 2), index=arrays)
>>> tuples = list(zip(*arrays))
>>> index = pd.MultiIndex.from_tuples(tuples,
names=['first', 'second'])
>>> df6 = pd.DataFrame(np.random.rand(3, 2), index=index)
>>> df2.set_index(["Date", "Type"])
數(shù)據(jù)去重
>>> s3.unique() # 返回唯一的值
>>> df2.duplicated('Type') # 檢查特定列重復(fù)的
>>> df2.drop_duplicates('Type',
keep='last') # 去重
>>> df.index.duplicated() # 檢查索引重復(fù)
數(shù)據(jù)聚合
groupby
>>> df2.groupby(by=['Date','Type']).mean()
>>> df4.groupby(level=0).sum()
>>> df4.groupby(level=0).agg({'a':lambda x:sum(x)/len(x),
'b': np.sum})
轉(zhuǎn)換 Transformation
transform?法,它與apply很像,但是對使?的函數(shù)有?定限制:
它可以產(chǎn)?向分組形狀?播標(biāo)量值 它可以產(chǎn)??個(gè)和輸?組形狀相同的對象 它不能修改輸?
>>> customSum = lambda x: (x+x%2)
>>> df4.groupby(level=0).transform(customSum)
缺失值處理
>>> df.dropna() # 刪除缺失值
>>> df3.fillna(df3.mean())# 用特定的值填充NaN值
>>> df2.replace("a", "f") # 使用其他值替換缺失值
數(shù)據(jù)合并
Merge
>>> pd.merge(data1,
data2,
how='left',
on='X1')

>>> pd.merge(data1,
data2,
how='right',
on='X1')

>>> pd.merge(data1,
data2,
how='inner',
on='X1')

>>> pd.merge(data1,
data2,
how='outer',
on='X1')

Join
join方法提供了一個(gè)簡便的方法用于將兩個(gè)DataFrame中的不同的列索引合并成為一個(gè)DataFrame。
其中參數(shù)的意義與merge方法基本相同,只是join方法默認(rèn)為左外連接how=left。
>>> data1.join(data2, how='right')
Concatenate
# 垂直拼接
>>> s.append(s2)
# 水平或垂直拼接
>>> pd.concat([s,s2],axis=1, keys=['One','Two'])
>>> pd.concat([data1, data2], axis=1, join='inner')
日期
>>> df2['Date']= pd.to_datetime(df2['Date'])
>>> df2['Date']= pd.date_range('2000-1-1',
freq='M')
>>> dates = [datetime(2012,5,1), datetime(2012,5,2)]
>>> index = pd.DatetimeIndex(dates)
>>> index = pd.date_range(datetime(2012,2,1), end, freq='BM')
可視化
Series可視化
>>> import matplotlib.pyplot as plt
>> s.plot()
>>> plt.show()
>>> df2.plot()
>>> plt.show()


相關(guān)閱讀:
