Series 和 DataFrame還未構建完成的朋友可以參考我的上一篇博文:https://www.cnblogs.com/zry-yt/p/11794941.html
當我們構建好了 Series 和 DataFrame 之后,我們會經常使用哪些功能呢?引用上一章節中的場景,我們有一些用戶的的信息,並將它們存儲到了 DataFrame 中。因為大多數情況下 DataFrame 比 Series 更為常用,所以這里以 DataFrame 舉例說明,但實際上很多常用功能對於 Series 也適用。
此為上一章節完成的DataFrame
import pandas as pd index = pd.Index(data=["Tom", "Bob", "Mary", "James"], name="name") data = { "age": [18, 30, 25, 40], "city": ["BeiJing", "ShangHai", "GuangZhou", "ShenZhen"], "sex": ["male", "male", "female", "male"] } user_info = pd.DataFrame(data=data, index=index) user_info """ age city sex name Tom 18 BeiJing male Bob 30 ShangHai male Mary 25 GuangZhou female James 40 ShenZhen male """
常用基本功能
了解數據的整體情況
user_info.info() """ <class 'pandas.core.frame.DataFrame'> Index: 4 entries, Tom to James Data columns (total 3 columns): age 4 non-null int64 city 4 non-null object sex 4 non-null object dtypes: int64(1), object(2) memory usage: 128.0+ bytes """
查看頭部、尾部的n條數據
查看頭部 --> .head(n)
# 查看前三條數據 user_info.head(3)
查看尾部 --> .tail(n)
# 查看最后兩條數據 user_info.tail(2)
獲取Pandas 中數據結構的方法和屬性
通過 .shape 獲取數據的形狀
user_info.shape # (4, 3) """ age city sex name Tom 18 BeiJing male Bob 30 ShangHai male Mary 25 GuangZhou female James 40 ShenZhen male """
通過 .T 獲取數據的轉置。
user_info.T """ name Tom Bob Mary James age 18 30 25 40 city BeiJing ShangHai GuangZhou ShenZhen sex male male female male """
通過 .values 獲取原有數據
user_info.values """ array([[18, 'BeiJing', 'male'], [30, 'ShangHai', 'male'], [25, 'GuangZhou', 'female'], [40, 'ShenZhen', 'male']], dtype=object) """
描述與統計
查看數據的簡單統計指標
user_info.age.max() # 查看年齡的最大值 user_info.age.min() # 查看年齡的最小值 user_info.age.mean() # 查看年齡的平均值 user_info.age.quantile() # 查看年齡的中位數 user_info.age.sum() # 查看年齡的總和 user_info.age.cumsum() # 累加求和 """ name Tom 18 Bob 48 Mary 73 James 113 Name: age, dtype: int64 """
一次性獲取多個統計指標
查看數字類型列的一些統計指標:如 總數、平均數、標准差、最小值、最大值、25% / 50% / 75% 分位數
user_info.describe()
查看非數字類型的列的統計指標:如 總數,去重后的個數、最常見的值、最常見的值的頻數
user_info.describe(include=["object"])
統計某列中每個值出現的次數
# 統計sex列值出現的次數 user_info.sex.value_counts() """ male 3 female 1 Name: sex, dtype: int64 """
獲取某列最大值或最小值對應的索引
# 獲取年齡最大的索引 user_info.age.idxmax() # 'James' # 獲取年齡最小的索引 user_info.age.idxmin() # 'Tom'
離散化
數值區間為(a,b]
.cut
根據每個值的大小來進行離散化,自動生成等距的離散區間
# 將年齡分成3個區間 pd.cut(user_info.age,3) """ name Tom (17.978, 25.333] Bob (25.333, 32.667] Mary (17.978, 25.333] James (32.667, 40.0] Name: age, dtype: category Categories (3, interval[float64]): [(17.978, 25.333] < (25.333, 32.667] < (32.667, 40.0]] """
自定義區間與標簽
pd.cut(user_info.age,[10,24,36,50],labels=["child",'youth',"middle"]) """ user_index Tom child Scott child Jass middle Jame middle Name: age, dtype: category Categories (3, object): [child < youth < middle] """
.qcut
根據每個值出現的次數來進行離散化
pd.qcut(user_info.age,3) """ name Tom (17.999, 25.0] Bob (25.0, 30.0] Mary (17.999, 25.0] James (30.0, 40.0] Name: age, dtype: category Categories (3, interval[float64]): [(17.999, 25.0] < (25.0, 30.0] < (30.0, 40.0]] """
練習
隨機生成 100 個數作為考試成績,給成績設定優良中差,比如:0-59 分為差,60-70 分為中,71-80 分為良,81-100 為優秀,統計每個區間上的人數。
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 種子 np.random.seed(10) # 生成0-100的隨機數字100個 data = np.random.randint(0,101,100) # 准備區間名字 labels=["差","中","良","優"] # 將區間顯示為自定義區間名 count=pd.cut(data,[-1,59,70,80,100],labels=labels) # 統計次數 count=count.value_counts() # 畫直方圖,橫軸為標簽,縱軸為數量 plt.bar(labels,count) # 防止中文編碼錯誤 plt.rcParams['font.sans-serif']=['SimHei']
排序功能
Pandas 支持兩種排序方式:
- 按軸(索引或列)排序
- 按實際值排序
按索引排序
.sort_index:默認是按照索引進行正序排的
user_info.sort_index()
按列名進行倒序排
設置參數 axis=1 和 ascending=False
user_info.sort_index(axis=1, ascending=False)
按照實際值來排序
.sort_values:后接需要排序的參數(默認升序)
# 按年齡排序 user_info.sort_values(by="age")
按照多個值來排序
# 先按年齡排序,再按城市排序
# list 中每個元素的順序會影響排序優先級
user_info.sort_values(by=["age", "city"])
獲取字段最大/小的 n 個值
# 獲取年齡最大的兩個值 user_info.age.nlargest(2) # 獲取年齡最小的兩個值 user_info.age.nsmallest (2) """ 注意:該方法比先排序再取head()或者tail()效率高 """
函數應用
雖說 Pandas 為我們提供了非常豐富的函數,有時候我們可能需要自己定制一些函數,並將它應用到 DataFrame 或 Series。常用到的函數有: map 、 apply 、 applymap 。
map 方法
map 是 Series 中特有的方法,通過它可以對 Series 中的每個元素實現轉換。
#通過年齡判斷用戶是否屬於中年人(30歲以上為中年) # 接收一個 lambda 函數 user_info.age.map(lambda x: "yes" if x >= 30 else "no") """ name Tom no Bob yes Mary no James yes Name: age, dtype: object """ # 通過城市來判斷是南方還是北方 city_map = { "BeiJing": "north", "ShangHai": "south", "GuangZhou": "south", "ShenZhen": "south" } # 傳入一個 map user_info.city.map(city_map) """ name Tom north Bob south Mary south James south Name: city, dtype: object """
apply方法
既支持 Series,也支持 DataFrame,在對 Series 操作時會作用到每個值上,在對DataFrame 操作時會作用到所有行或所有列(通過 axis 參數控制)
對 Series 來說,apply 方法 與 map 方法區別不大。
user_info.age.apply(lambda x: "yes" if x >= 30 else "no")
對 DataFrame 來說,apply 方法的作用對象是一行或一列數據(一個Series)
user_info.apply(lambda x: x.max(), axis=0) """ age 40 city ShenZhen sex male dtype: object """
applymap 方法
applymap 方法針對於 DataFrame,它作用於 DataFrame 中的每個元素,它對 DataFrame 的效果類似於 apply 對 Series 的效果
# .upper()將所有的英文字母大寫 # .lower()將所有的英文字母小寫 user_info.applymap(lambda x: str(x).upper()) """ age city sex name Tom 23 BEIJING MALE Bob 30 SHANGHAI MALE Mary 25 GUANGZHOU FEMALE James 40 SHENZHEN MALE """
修改列/ 索引名稱
.rename ()
修改列
user_info.rename(columns={"age": "Age", "city": "City", "sex": "Sex"})
修改索引
user_info.rename(index={"Tom": "tom", "Bob": "bob"})
類型操作
獲取每種類型的列數
user_info.get_dtype_counts() """ int64 1 object 2 dtype: int64 """
轉換數據類型
user_info["age"].astype(float) """ name Tom 23.0 Bob 30.0 Mary 25.0 James 40.0 Name: age, dtype: float64 """
將 object 類型轉為其他類型
object --> 數字 --> .to_numeric
object --> 日期 --> .to_datetime
object --> 時間差 --> .to_timedelta
#添加身高字段 user_info["height"] = ["178", "168", "178", "180cm"] """ age city sex height name Tom 23 BeiJing male 178 Bob 30 ShangHai male 168 Mary 25 GuangZhou female 178 James 40 ShenZhen male 180cm """
""" 將身高這一列轉為數字,很明顯,180cm 並非數字,為了強制轉換,我們可以傳入 errors 參數,這個參數的作用是當強轉失敗時的處理方式。 默認情況下errors='raise':意味着強轉失敗后直接拋出異常 設置errors='coerce':可以在強轉失敗時將有問題的元素賦值為 pd.NaT(對於datetime或timedelta)或 np.nan(數字) 設置 errors='ignore':可以在強轉失敗時返回原有的數據。 """ pd.to_numeric(user_info.height, errors="coerce") """ name Tom 178.0 Bob 168.0 Mary 178.0 James NaN Name: height, dtype: float64 """ pd.to_numeric(user_info.height, errors="ignore") """ name Tom 178 Bob 168 Mary 178 James 180cm Name: height, dtype: object """