參考天池AI
github部落格傳送門
部落格園傳送門
安裝pandas
通過指令提示符 pip install pandas
或者通過第三方發放版 Anaconda 進行滑鼠操作安裝
Numpy學習教程傳送門
https://blog.csdn.net/zhanghao3389/article/details/82791862
Series 的建立
import numpy as np, pandas as pd
# 通過一維數組建立序列
arr1 = np.arange(10) # 建立一個0~9的numpy數組對象
print(arr1) # 列印這個數組
print(type(arr1)) #列印這個數組的類型
s1 = pd.Series(arr1) # 将數組轉換為 Series
print(s1) # 列印出這個Series
print(type(s1)) # 列印出這個Series的資料類型類型
通過字典的方式建立序列
dic1 = {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50} # 建立一個字典dic1
print(dic1) # 列印這個字典
print(type(dic1)) # 列印這個字典的資料類型
s2 = pd.Series(dic1) # 将這個字典轉換為Series
print(s2) # 列印轉換後的Series
print(type(s2)) #列印轉化後的Series資料類型
DataFrame的建立
資料框的建立主要有三種方式
1.通過二維數組建立資料框
arr2 = np.array(np.arange(12)).reshape(4, 3) # 建立一個0~11的數組,然後reshape成4*3的矩陣
print(arr2) # 列印出這個矩陣
print(type(arr2)) # 列印出這個矩陣的資料類型
df1 = pd.DataFrame(arr2) # 将這個矩陣轉換為 DataFrame
print(df1) # 列印出轉換後的DataFrame
print(type(df1)) # 列印出這個DataFrame的資料類型
2.通過字典的方式建立資料框
(1)字典清單
dic2 = {'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [9, 10, 11, 12], 'd': [13, 14, 15, 16]} # 建立一個字典
print(dic2) # 列印出這個字典的内容
print(type(dic2)) # 列印出這個字典的資料類型
df2 = pd.DataFrame(dic2) # 将這個字典轉換為DataFrame
print(df2) # 列印出轉化後的DataFrame
print(type(df2)) # 列印出這個DataFrame的資料類型
(2)嵌套字典
dic3 = {'one': {'a': 1, 'b': 2, 'c': 3, 'd': 4}, 'two': {'a': 5, 'b': 6, 'c': 7, 'd': 8},
'three': {'a': 9, 'b': 10, 'c': 11, 'd': 12}} # 建立了一個嵌套的字典
print(dic3) # 列印出這個嵌套的字典
print(type(dic3)) # 列印出這個字典的資料類型
df3 = pd.DataFrame(dic3) # 将這個嵌套字典轉換為DataFrame
print(df3) # 列印出轉換後的DataFrame
print(type(df3)) # 列印出這個DataFrame的資料類型
3.通過資料框的方式建立資料框
df4 = df3[['one', 'three']] # 通過調用df3中的兩列資料進行建立DataFrame
print(df4) # 列印出這個調用df3中資料的DataFrame
print(type(df4)) # 列印出這個DataFrame的資料類型
s3 = df3['one'] # 通過調用df3中的一列資料進行建立DataFrame會建立出Series
print(s3) # 列印出這個Series
print(type(s3)) # 列印出這個Series的資料類型
通過索引值或索引标簽擷取資料
import numpy as np, pandas as pd
s4 = pd.Series(np.array([1, 1, 2, 3, 5, 8])) # 建立一個Series資料
print(s4) # 列印出這個資料
print(s4.index) # 列印出這個資料的索引
現在我們為序列設定一個自定義的索引值:
s4.index = ['a', 'b', 'c', 'd', 'e', 'f'] # 手動修改s4這個資料的索引(index)
print(s4) # 列印修改索引後的Series
print('s4[3]:\n', s4[3]) # 取出下标為 3 的資料
print('s4[e]:\n', s4['e']) # 取出索引為 e 的資料
print('s4[1,3,5]:\n', s4[[1, 3, 5]]) # 取出下标為 1 3 5 的資料
print("s4[['a','b','d','f']]:\n", s4[['a', 'b', 'd', 'f']]) # 取出索引為 a b d f 的資料
print('s4[:4]:\n', s4[:4]) # 切片到下标為 4 的所有資料
print("s4['c':]:\n", s4['c':]) # 切片索引為 c 開始後面所有的資料
print("s4['b':'e']:\n", s4['b':'e']) # 切片索引為 b 開始 e 結束(左閉右開)的所有資料
自動化對齊
如果有兩個序列,需要對這兩個序列進行算術運算,這時索引的存在就展現的它的價值了—自動化對齊.
s5 = pd.Series(np.array([10, 15, 20, 30, 55, 80]), index=['a', 'b', 'c', 'd', 'e', 'f']) # 建立一個Series并指定索引
print(s5) # 列印出這個Series
s6 = pd.Series(np.array([12, 11, 13, 15, 14, 16]), index=['a', 'c', 'g', 'b', 'd', 'f']) # 建立一個Series并指定索引
print(s6) # 列印出這個Series
print(s5 + s6) # 将兩個Series進行相加操作
print(s5 / s6) # 将兩個Series進行相除操作
# 由于s5中沒有對應的g索引,s6中沒有對應的e索引,是以資料的運算會産生兩個缺失值NaN。
# 注意,這裡的算術結果就實作了兩個序列索引的自動對齊,而非簡單的将兩個序列加總或相除對于資料框的對齊,不僅僅是行索引的自動對齊,同時也會自動對齊列索引(變量名)
利用pandas查詢資料
import pandas as pd
# 可以通過布爾索引有針對的選取原資料的子集、指定行、指定列等。
stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John', 'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
# 建立了一個DataFrame資料框
student = pd.DataFrame(stu_dic)
查詢資料的前5行或末尾5行 student.head() student.tail()
print(student) # 列印這個資料框
print('前五行:\n', student.head()) # 查詢這個資料框的前五行
print('後五行:\n', student.tail()) # 查詢這個資料框的後五行
查詢指定的行
print(student.loc[[0, 2, 4, 5, 7]]) # 這裡的loc索引标簽函數必須是中括号[]
查詢指定的列
print(student[['Name', 'Height', 'Weight']].head()) # 如果多個列的話,必須使用雙重中括号
也可通過loc索引标簽查詢指定的列
print(student.loc[:, ['Name', 'Height', 'Weight']].head)
查詢出所有12歲以上的女生資訊
print(student[(student['Sex'] == 'F') & (student['Age'] > 12)])
查詢出所有12歲以上的女生姓名,身高和體重
print(student[(student['Sex'] == 'F') & (student['Age'] > 12)][['Name', 'Height', 'Weight']])
利用pandas的DataFrames進行統計分析
import numpy as np, pandas as pd
np.random.seed(1234)
d1 = pd.Series(2 * np.random.normal(size=100) + 3)
d2 = np.random.f(2, 4, size=100)
d3 = np.random.randint(1, 100, size=100)
print('非空元素計算: ', d1.count()) # 非空元素計算
print('最小值: ', d1.min()) # 最小值
print('最大值: ', d1.max()) # 最大值
print('最小值的位置: ', d1.idxmin()) # 最小值的位置,類似于R中的which.min函數
print('最大值的位置: ', d1.idxmax()) # 最大值的位置,類似于R中的which.max函數
print('10%分位數: ', d1.quantile(0.1)) # 10%分位數
print('求和: ', d1.sum()) # 求和
print('均值: ', d1.mean()) # 均值
print('中位數: ', d1.median()) # 中位數
print('衆數: ', d1.mode()) # 衆數
print('方差: ', d1.var()) # 方差
print('标準差: ', d1.std()) # 标準差
print('平均絕對偏差: ', d1.mad()) # 平均絕對偏差
print('偏度: ', d1.skew()) # 偏度
print('峰度: ', d1.kurt()) # 峰度
print('描述性統計名額: ', d1.describe()) # 一次性輸出多個描述性統計名額
# 必須注意的是,descirbe方法隻能針對序列或資料框,一維數組是沒有這個方法的
這裡自定義一個函數,将這些統計描述名額全部彙總到一起:
def stats(x):
return pd.Series([x.count(), x.min(), x.idxmin(), x.quantile(.25), x.median(), x.quantile(.75),x.mean(), x.max(), x.idxmax(), x.mad(), x.var(), x.std(), x.skew(), x.kurt()],index=['Count', 'Min', 'Whicn_Min', 'Q1', 'Median', 'Q3', 'Mean', 'Max','Which_Max', 'Mad', 'Var', 'Std', 'Skew', 'Kurt'])
print(stats(d1)) # 列印統計後的名額
将這個函數 應用到每一列中
df = pd.DataFrame(np.array([d1,d2,d3]).T,columns=['x1','x2','x3'])
print(df.head())
print(df.apply(stats))
連續變量的相關系數(corr)和協方差矩陣(cov)的求解
print(df.corr())
相關系數的計算可以調用pearson方法或kendell方法或spearman方法,預設使用pearson方法。
print(df.corr('spearman'))
關注某一個變量與其餘變量的相關系數的話,可以使用corrwith,如下方隻關心x1與其餘變量的相關系數
print(df.corrwith(df['x1']))
數值型變量間的協方差矩陣
print(df.cov())
利用pandas實作SQL操作
import pandas as pd, numpy as np
# 原資料
stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John', 'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
student = pd.DataFrame(stu_dic) # 将資料轉換為DataFrame
print(student) # 列印出這個資料
增
添加新行或增加新列
dic = {'Name': ['LiuShunxiang', 'Zhangshan'], 'Sex': ['M', 'F'], 'Age': [27, 23], 'Height': [165.7, 167.2],'Weight': [61, 63]} # 需要增加的資料
student2 = pd.DataFrame(dic) # 增加資料
print(student2) # 列印出增加資料後的DataFrame
現在将student2中的資料新增到student中 可以通過 concat函數實作
student3 = pd.concat([student, student2])
print(student3)
注意 注意到了嗎?在資料庫中union必須要求兩張表的列順序一緻,而這裡concat函數可以自動對齊兩個資料框的變量!
新增列的話,其實在pandas中就更簡單了,例如在student2中新增一列學生成績
print(pd.DataFrame(student2, columns=['Age', 'Weight', 'Name', 'Sex', 'Weight', 'Score']))
删
删除資料框student2通過del指令實作,該指令可以删除Python的所有對象
del student2 # 删除資料框 student2, 通過del指令可以删除Python的所有對象
print(student2)
删除指定的行
print(student.drop([0, 1, 3, 6]))
删除所有14歲以下的學生
print(student['Age'] > 14)
删除指定的列
print(student.drop(['Height', 'Weight'], axis=1).head()) # axis預設為0選擇行
改
修改原始記錄的 結合布爾索引和指派的方法
student3.loc[student3['Name'] == 'LiuShunxiang', 'Height'] = 173
print(student3[student3['Name'] == 'LiuShunxiang'][['Name', 'Height']])
查
有關資料查詢部分
聚合,排序和多表連接配接操作
聚合:pandas子產品中可以通過groupby()函數實作資料的聚合操作
print(student.groupby('Sex').mean())
如果不對原始資料作限制的話,聚合函數會自動選擇數值型資料進行聚合計算。如果不想對年齡計算平均值的話,就需要剔除改變量
print(student.drop('Age', axis=1).groupby('Sex').mean())
groupby還可以使用多個分組變量,例如根本年齡和性别分組,計算身高與體重的平均值
print(student.groupby(['Sex', 'Age']).mean())
對每個分組計算多個統計量
print(student.drop('Age', axis=1).groupby('Sex').agg([np.mean, np.median]))
排序
使用sort_index和sort_values實作序列和資料框的排序工作
Data = pd.Series(np.array(np.random.randint(1, 20, 10)))
print(Data)
print(Data.sort_index())
print(Data.sort_values(ascending=False))
資料框中一般都是按值排序
print(student.sort_values(by=['Age', 'Height']))
多表連接配接
多表之間的連接配接也是非常常見的資料庫操作,連接配接分内連接配接和外連接配接,
在資料庫語言中通過join關鍵字實作,pandas我比較建議使用merger函數實作資料的各種連接配接操作。
如下是構造一張學生的成績表:
dic2 = {'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'Jeffrey', 'Judy', 'Philip', 'Robert', 'Willam'], 'Score': [88, 76, 89, 67, 79, 90, 92, 86, 73, 77]}
score = pd.DataFrame(dic2)
print(score)
現在想把學生表student與學生成績表score做一個關聯
stu_score1 = pd.merge(student, score, on='Name')
print(stu_score1)
注意,預設情況下,merge函數實作的是兩個表之間的内連接配接,即傳回兩張表中共同部分的資料。
可以通過how參數設定連接配接的方式,left為左連接配接;right為右連接配接;outer為外連接配接。
stu_score2 = pd.merge(student, score, on='Name', how='left')
print(stu_score2)
利用pandas進行缺失值的處理
三類方法 删除法 填補法 插值法
删除法:當資料中的某個變量大部分值都是缺失值,可以考慮删除改變量;當缺失值是随機分布的,且缺失的數量并不是很多是,也可以删除這些缺失的觀測。
替補法:對于連續型變量,如果變量的分布近似或就是正态分布的話,可以用均值替代那些缺失值;如果變量是有偏的,可以使用中位數來代替那些缺失值;對于離散型變量,我們一般用衆數去替換那些存在缺失的觀測。
插補法:插補法是基于蒙特卡洛模拟法,結合線性模型、廣義線性模型、決策樹等方法計算出來的預測值替換缺失值。
import pandas as pd, numpy as np
stu_score = {'Score': [88.0, 76.0, 89.0, 67.0, 79.0, None, None, None, 90.0, None, None, 92.0, None, None, 86.0, 73.0, None, None, 77.0]}
stu_score2 = pd.DataFrame(stu_score)
s = stu_score2['Score']
print(s)
# 結合sum函數和isnull函數來檢測資料中含有多少缺失值
print('缺失值個數:', sum(pd.isnull(s)))
直接删除缺失值
print('s.dropna():\n', s.dropna())
預設情況下,dropna會删除任何含有缺失值得行,我們再構造一個資料庫試試
df = pd.DataFrame([[1, 1, 2], [3, 5, np.nan], [13, 21, 34], [55, np.nan, 10], [np.nan, np.nan, np.nan], [np.nan, 1, 2]], columns=('x1', 'x2', 'x3'))
print('df:\n', df)
print('df.dropna():\n', df.dropna())
使用一個常量來填補缺失值,可以使用fillna函數實作簡單的填補工作
print('df.fillna(0):\n', df.fillna(0)) # 用 0 填補所有缺失值
采用前項填充或後項填充
print('method="ffill":\n', df.fillna(method='ffill'))
print('method="bfill":\n', df.fillna(method='bfill'))
使用常量填充不同的列
print("{'x1': 1, 'x2': 2, 'x3': 3}:\n", df.fillna({'x1': 1, 'x2': 2, 'x3': 3}))
x1_median = df['x1'].median()
x2_mean = df['x2'].mean()
x3_mean = df['x3'].mean()
print(x1_median)
print(x2_mean)
print(x3_mean)
print(df.fillna({'x1': x1_median, 'x2': x2_mean, 'x3': x3_mean}))
在使用填充法時,相對于常數填充或前項、後項填充,使用各列的衆數、均值或中位數填充要更加合理一點,這也是工作中常用的一個快捷手段。
利用pandas實作Excel的資料透視表功能
import pandas as pd, numpy as np
# pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='ALL')
# data:需要進行資料透視表操作的資料框
# values:指定需要聚合的字段
# index:指定某些原始變量作為行索引
# columns:指定哪些離散的分組變量
# aggfunc:指定相應的聚合函數
# fill_value:使用一個常數替代缺失值,預設不替換
# margins:是否進行行或列的彙總,預設不彙總
# dropna:預設所有觀測為缺失的列
# margins_name:預設行彙總或列彙總的名稱為'All'
stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John', 'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
student = pd.DataFrame(stu_dic)
對一個分組變量(Sex),一個數值變量(Height)作統計彙總
Table1 = pd.pivot_table(student, values=['Height'], columns=['Sex'])
print(Table1)
對一個分組變量(Sex),兩個數值變量(Height,Weight)做統計彙總
Table2 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex'])
print(Table2)
對兩個分組變量(Sex, Age), 兩個數值變量(Height, Weight)做統計彙總
Table3 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex', 'Age'])
print(Table3)
很顯然這樣的結果并不像Excel中預期的那樣,該如何變成列聯表的形式的?很簡單,隻需将結果進行非堆疊操作(unstack)即可
Table4 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex', 'Age']).unstack()
print(Table4)
使用多個聚合函數
Table5 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex'], aggfunc=[np.mean, np.median, np.std])
print(Table5)
有關更多資料透視表的操作,可參考http://python.jobbole.com/81212/
多層索引的使用
Series的階層化索引,索引是一個二維數組,相當于兩個索引決定一個值
有點類似于DataFrame的行索引和列索引
import pandas as pd, numpy as np
s = pd.Series(np.arange(1, 10), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 2, 3, 1, 2, 3]])
print('s:\n', s)
print('s.index:\n', s.index)
# 選取外層索引為 a 的資料
print("s['a']:\n", s['a'])
# 選取外層索引為 a 和内層索引為 1 的資料
print("s['a', 1]:\n", s['a', 1])
# 選取外層索引為 a 和内層索引為 1,3的資料
print("s['a'][[1, 3]]:\n", s['a'][[1, 3]])
# 階層化索引的切片,包括右端的索引
print('s[["a", "c"]]:\n', s[['a', 'c']])
print('s["b":"d"]:\n', s['b':'d'])
# 通過unstack方法可以将Series變成一個DataFrame
# 資料的類型以及資料的輸出結構都變成了DataFrame,對于不存在的位置使用NaN填充
print('s.unstack():\n', s.unstack())
DataFrame的階層化索引
data = pd.DataFrame(np.random.randint(0, 150, size=(8,12)),columns=pd.MultiIndex.from_product([['模拟考', '正式考'],['數學', '國文', '英語', '實體', '化學', '生物']]),index=pd.MultiIndex.from_product([['期中', '期末'],['雷軍', '李斌'],['測試一', '測試二']]))
print('data:\n', data)
print('data["模拟考"]["國文","數學"]:\n', data['模拟考'][['國文', '數學']])
print("data.loc['期中', '雷軍', '測試一']['模拟考', '數學']:\n", data.loc['期中', '雷軍', '測試一']['模拟考', '數學'])
print("data.loc['期中', '雷軍', '測試一']:\n", data.loc['期中', '雷軍', '測試一'])
print("data['正式考']:\n", data['正式考'])