天天看點

Pandas常用操作Series 的建立DataFrame的建立通過索引值或索引标簽擷取資料利用pandas查詢資料利用pandas的DataFrames進行統計分析利用pandas實作SQL操作排序利用pandas進行缺失值的處理利用pandas實作Excel的資料透視表功能多層索引的使用

參考天池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['正式考'])
                

繼續閱讀