重點,敲黑板了
- 首先,本文遵循,傳統教學,點到為止!只介紹個人使用比較頻繁的一些函式或處理方式,
- 本文的示例只是演示所用,示例一般是不修改原資料的,如果代碼會修改原資料會標明(在原資料上進行修改),自己使用時一定要注意是否修改了原資料,一旦報錯,首先檢查自己的代碼是否改變了原資料,
# 未修改原資料 df.drop('name', axis = 1) # 修改原資料 df.drop('name', axis = 1, inplace=True) # 修改原資料 df = df.drop('name', axis = 1)
pandas之所以強大是因為它擁有各種資料處理的函式,各個函式互相組合,靈活多變,并且與numpy、matplotlib、sklearn、>pyspark、sklearn等眾多科學計算庫互動,真正想要融會貫通實戰是必經之路,- 原創不易,碼字也很累,如果覺得文章不錯,💗 一定記得三連哦💗 ~ 在此提前感謝各位,

文章目錄
- DataFrame創建
- 創建空的 DataFrame
- 常規 DataFrame 創建方式
- DataFrame存盤
- 常見存盤方式(csv, json, excel, pickle)
- DataFrame查看資料資訊
- 顯示摘要資訊
- 顯示描述性統計資訊
- 顯示 前 / 后 n行
- 顯示索引、列資訊
- 顯示每列的資料型別
- 顯示占用的記憶體大小
- 定位某行資料
- 使用 loc() 定位
- 使用 iloc 定位
- 添加一行資料
- 使用 loc 定位并添加
- 使用 append 添加
- 洗掉資料
- 根據列名洗掉列
- 根據索引洗掉行
- 使用 loc 定位資料并洗掉
- 使用 del 洗掉列
- 同時洗掉行、列
- 洗掉重復值
- 篩查重復值
- 判斷某列是否有重復值
- 判斷 DataFrame 是否有重復行
- 統計重復行的數量
- 顯示重復的資料行
- 缺失值處理
- 查找缺失值
- 查找非缺失值
- 顯示有缺失值的行
- 洗掉缺失值
- 填充缺失值
- 數字或字串填充
- 用缺失值 前/后 的值填充
- 用缺失值所在列的 均值/中位數 等填充
- 列操作
- 修改列名
- 修改列型別
- 將列進行拆分得到多列
- 將多列合并成新列
- 對數值列磁區
- 排序
- 索引排序
- 重置索引
- 值排序
- 創建排名列
- 分組
- 對行分組統計
- 對不同列使用不同的統計函式
- DataFrame合并
- merge()
- concat()
- append()
- DataFrame時間處理
- 將字串列轉化成時間序列
- 將時間列作為索引
- 獲取時間的各個屬性
- 重采樣 resample()
- DataFrame遍歷方式
- iterrows() - 遍歷行(索引,列值序列)
- iteritems() - 遍歷(列名,值)
- itertuples() - 遍歷行 (索引,列值A,列值B..)
DataFrame創建
創建空的 DataFrame
創建一個空的 , 包含三行空資料,
df = pd.DataFrame(columns=['name', 'age'], index=[0, 1, 2])

常規 DataFrame 創建方式
這里只介紹常見的三種,陣列創建、字典創建、外部檔案創建,常見檔案讀取的時候直接指定檔案路徑即可,對于 xlsx 檔案可能存在多個 sheet 這時就需要指定 sheet_name ,
# 陣列創建
df = pd.DataFrame(data=[['路飛', 18],
['索隆', 19],
['娜美', 18]],
columns=['name', 'age'])
# 通過字典創建
df = pd.DataFrame({'name': ['路飛','索隆', '娜美'],
'age':[18, 19, 18]})
# 通過外部檔案創建,csv,xlsx,json等
df = pd.read_csv('XXX.csv')

DataFrame存盤
常見存盤方式(csv, json, excel, pickle)
保存時,一般情況下是不需要保存索引的,因為讀取的時候會自動生成索引,
df.to_csv('test.csv', index=False) # 忽略索引
df.to_excel('test.xlsx', index=False) # 忽略索引
df.to_json('test.json') # 保存為json
df.to_pickle('test.pkl') # 保存為二進制格式
DataFrame查看資料資訊
顯示摘要資訊
在我們使用 DataFrame 之前都會查看資料的資訊,個人首選 info ,它展現了資料集的行列資訊,以及每列中的非空值的數量,
df.info()

顯示描述性統計資訊
能夠較為直觀的查看數值列的基本統計資訊,
df.describe()

顯示 前 / 后 n行
默認顯示5行,可指定顯示的行數,
df.head(n) # 可指定整數,輸出前面n行
df.tail(n) # 可指定整數,輸出后面n行
顯示索引、列資訊
顯示索引及列的基本資訊,
df.columns # 列資訊
df.index # 索引資訊

顯示每列的資料型別
顯示列的名稱及對應的資料型別,
df.dtypes

顯示占用的記憶體大小
顯示給列占用記憶體的大小,單位是 :位元組(byte),
df.memory_usage()

定位某行資料
重點:無論是 loc 還是 iloc 使用的要領都是先指定行,再指定列,并且行與列運算式用 , 分隔,如:df.loc[:, :] 獲取所有行所有列的資料,
使用 loc() 定位
比如現在要定位 [索隆] 這行資料,有以下
df.loc[1, :] # loc[index , columns] 行索引,列名,回傳 Series 物件
df.loc[df['age'] > 18] # 回傳 DataFrame 物件
# 或者 df[df['age'] > 18]
# df.loc[df['name'] == '索隆']

使用 iloc 定位
使用 iloc 取第二行(索引從0開始),所有列的資料,
df.iloc[1, :] # iloc[index1, index2] 行索引, 列索引

添加一行資料
使用 loc 定位并添加
使用 loc 定位到 index = 3 的行,再進行賦值(在原資料上進行修改)
df.loc[len(df)] = ['喬巴', 3]

使用 append 添加
append 添加資料時需要指定列名,列值,如果某列未指定的話,則默認填充 NaN,
df.append({'name': '山治', 'age': 19}, ignore_index=True)

洗掉資料
根據列名洗掉列
使用 drop 來洗掉某列,指定要洗掉的軸,與對應 列/行 的 名稱/索引,
df.drop('name', axis = 1) # 洗掉單列
df.drop(['name', 'age'], axis = 1) # 洗掉多列

根據索引洗掉行
與上面洗掉列的方式相似,不過這里指定的是索引,
df.drop(0, axis=0) # 洗掉單行
df.drop([0, 1], axis=0) # 洗掉多行

使用 loc 定位資料并洗掉
先使用 loc 定位某條件的資料,再獲取索引 index ,然后使用 drop 洗掉,
df.drop(df.loc[df['name'] == '娜美'].index, axis=0) # 洗掉定位到的行

使用 del 洗掉列
del 是在原資料上進行修改,使用是要注意,
del df['age']

同時洗掉行、列
drop 也可以同時指定行列進行洗掉,這里洗掉第一、二行并洗掉 age 列,
df.drop(columns=['age'], index=[0, 1])

洗掉重復值
- 指定
subset,則根據指定的列作為參考進行去重,即如果某兩行a值相同,則會洗掉第二次的出現的那一行,只保留第一次 - 不指定
subset,則根據所有列作為參考進行去重,只有兩行資料 完全相同 才會進行去重,
df.drop_duplicates(subset=['a'], keep='first')
df.drop_duplicates(keep='first')

篩查重復值
示例資料
df = pd.DataFrame({'name':['Python',
'Python',
'Java',
'Java',
'C'],
'count': [2, 2, 6, 8, 10]})

判斷某列是否有重復值
使用 values_counts() 對列中各值出現次數進行統計,結果默認按照降序進行排列,只需要判斷第一行值的出現次數是否為1即可判斷是否存在重復值,
df['a'].value_counts()

使用 drop_duplicates() 對重復值進行洗掉,只保留第一次出現的值,判斷處理后的值是否與原 df 相等,如果 False 就表示有重復值,
df.equals(df.drop_duplicates(subset=['a'], keep='first'))
False
判斷 DataFrame 是否有重復行
同樣是使用 drop_duplicates() 對重復值進行洗掉,只保留第一次出現的值,此時不使用 subset 引數設定列,默認為全部列,判斷處理后的值是否與原 df 相等,如果 False 就表示有重復值,
df.equals(df.drop_duplicates(keep='first'))
False
統計重復行的數量
注意這里的統計是參照所有列來的,只有兩行完全相同才會判斷為重復行,所以統計的結果是 1 ,
len(df) - len(df.drop_duplicates(keep="first"))
1
顯示重復的資料行
先洗掉重復的行,只保留第一次出現的,得到一個 行唯一 的資料集,再使用 drop_duplicates() 洗掉掉 df 中存在重復的所有資料,這次不保留第一次出現的重復值,將上述兩個結果集進行合并,使用 drop_duplicates() 對新生成的資料集進行去重,即可得到重復行的資料,
df.drop_duplicates(keep="first")\
.append(df.drop_duplicates(keep=False))\
.drop_duplicates(keep=False)

缺失值處理
查找缺失值
缺失值為 True ,非缺失值為 False ,
df.isnull()

查找非缺失值
非缺失值為 True ,缺失值為 False ,
df.notnull()

顯示有缺失值的行
.isnull:查找缺失值,主要為了將缺失值的位置標 True,
.T:行列轉置,為下一步 any 做準備,
.any:一個序列中滿足一個 True,則回傳 True,
df[df.isnull().T.any()]

洗掉缺失值
這里的引數需要注意的比較多,這里著重講一下,
- axis:0 行,1 列
- how:
- any:如果有 NaN,洗掉該行或列,
- all:如果所有值都是 NaN,洗掉該行或列,
- thresh:指定 NaN 的數量,當 NaN 數量達到才洗掉,
- subset:要考慮的資料范圍,如:洗掉缺失行,就用subset指定參考的列,默認是所有列,
- inplace:是否修改原資料,
# 某行如果有缺失值,則洗掉這一行
df.dropna(axis=0, how='any')
# 某列如果有缺失值,則洗掉這一列
df.dropna(axis=1, how='any')

填充缺失值
數字或字串填充
直接指定要填充的數字或字串,
df.fillna(0)

用缺失值 前/后 的值填充
- 用缺失值的前一個值(該列上面一個值)填充,如果缺失值在第一行則不填充
- 用缺失值的后一個值(該列下面一個值)填充,如果缺失值在最后一行則不填充
df.fillna(method='pad')
df.fillna(method='bfill')

用缺失值所在列的 均值/中位數 等填充
可以用該列的統計資訊來進行填充,如使用 mean、median、max、min、sum 填充等,
df.fillna(df.mean())

列操作
修改列名
df.columns 是直接指定新的列名來替換所有的列名, (在原資料上進行修改)
rename() 需要指定原名與新名來進行替換,
df.columns = ['new_name', 'new_age']
df.rename(columns=({'name':'new_name','age':'new_age'}))

修改列型別
使用 astype 來修改列型別,
df['age'].astype(str)

將列進行拆分得到多列
split 只能對字串列進行拆分,
df[['name1', 'name2']] = df['name'].str.split(',', expand=True)

將多列合并成新列
同樣合并也是字串型別的列才能進行合并,
df['all'] = df['name'] + '/' + df['age'].astype(str)

對數值列磁區
對于數值列,實際使用的時候可能需要根據指定的范圍,將這些數值變為標簽值,如衡量產品的指標及格、不及格,成績是否優秀等,使用是需要指定數值列、各個標簽的臨界值,臨界值的開閉情況(示例中:默認 left=True ,指定 right=False ,即左閉右開),最后指定標簽的名稱即可,
df['評價'] = pd.cut(df['成績'], [0, 60, 80, np.inf],
right=False, labels=['不及格', '良好', '優秀'])

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

重置索引
將索引重新排序,原來的索引不保留,
df.reset_index(drop=True)

值排序
先按照名字降序排序,再對相同名字下的成績進行降序排序,
df.sort_values(by=['名字', '成績'], axis=0, ascending=False)

創建排名列
使用 rank 來進行排名,主要引數 method 的取值含義如下:
method | 含義 |
|---|---|
average | 默認值,在名次一樣的分組中,為各個值分配平均排名(平均數),排名之間存在跳躍 |
min | 使用分組中的最小排名,排名之間存在跳躍 |
max | 使用分組中的最大排名,排名之間存在跳躍 |
first | 按值在原始資料中的出現順序進行排名,排名之間存在跳躍 |
dense | 同一個分組的排名相同,排名之間不存在跳躍 |
現在按照 成績 列對每行資料進行排名,并新建排名列,幾種排名方式下面都已給出,
df['排名'] = df['成績'].rank(method='average', ascending=False)

分組
對行分組統計
現在對各人的成績進行分組計算,分別計算總和、均值、最大值,
df.groupby(['名字']).sum()
df.groupby(['名字']).mean()
df.groupby(['名字']).max()

注意:此時的索引為 名字,如果想要重置索引,可以使用如下方式,
df.groupby(['名字']).sum().reset_index()

對不同列使用不同的統計函式
agg() 是指定函式使用在某個數列上,然后回傳標量值,
apply() 是先將資料拆分 >>> 再應用 >>> 最后匯總的程序(只能應用單個函式),回傳多維的資料,
df.groupby(['名字']).agg({'成績':['sum','mean','max']})
df.groupby(['名字']).apply(max)

DataFrame合并
pandas中的合并函式主要是:merge()、concat()、append(),一般用來連接兩個及以上 DataFrame ,其中,concat(), append() 用來縱向連接 DataFrame 物件, merge() 用來橫向連接 DataFrame 物件,
三者對比:
concat()
- 連接多個DataFrame
- 設定特定的鍵(key)
append()
- 連接多個DataFrame
merge()
- 指定列來連接DataFrame
merge()
on 若指定則該列必須同時出現在這兩個 DataFrame 中,默認值為兩個 DataFrame 列中的交集,在本例中即使不指定 on ,實際默認值也會按照 name 列來進行合并,
how 引數詳解:
- inner:根據
on指定的列取交集, - outer:根據
on指定的列取并集, - left:根據
on指定的列并以左連接的方式合并, - right:根據
on指定的列并以右連接的方式合并,
pd.merge(df1, df2, on='name', how = "inner")
pd.merge(df1, df2, on='name', how = "outer")
pd.merge(df1, df2, on='name', how = "left")
pd.merge(df1, df2, on='name', how = "right")

concat()
concat() 可以多個 DataFrame 進行合并,根據實際情況可以選擇縱向合并還是橫向合并,具體看下面的示例,
# 多個DataFrame縱向合并取交集
pd.concat([df1, df2], ignore_index=True, join='inner',axis=0)
# 多個DataFrame縱向合并取并集
pd.concat([df1, df2], ignore_index=True, join='outer',axis=0)
# 多個DataFrame橫向合并取交集
pd.concat([df1, df2], ignore_index=False, join='inner',axis=1)
# 多個DataFrame橫向合并取并集
pd.concat([df1, df2], ignore_index=False, join='outer',axis=1)

另外還可以指定 key ,在索引的位置添加原資料的名稱,
pd.concat([df1, df2], ignore_index=False, join='outer', keys=['df1', 'df2'])

append()
append() 常用于縱向合并,也可以多個 DataFrame 進行合并,
df1.append(df2, ignore_index=True)
df1.append([df1, df2], ignore_index=True)

DataFrame時間處理
示例資料

將字串列轉化成時間序列
有時從 csv 或 xlsx 檔案中讀取的時間,是字串(Object)型別,這時就需要將其轉化成 datetime 型別,方便后續對時間的處理,
pd.to_datetime(df['datetime'])
將時間列作為索引
對于大部分時間序列資料,我們都可以將該列作為索引,來最大的利用時間,這里 drop=False 選擇不洗掉 datetime 列,
df.set_index('datetime', drop=False)

通過索引獲取 1月 的資料,這里顯示前五行,
df.loc['2021-1'].head()

通過索引獲取 1~3月 的資料,
df.loc['2021-1':'2021-3'].info()

獲取時間的各個屬性
這里給出一般需求中可能會用到的屬性,同時給出各個方法的實體,
| 常見屬性 | 描述 |
|---|---|
date | 獲取日期 |
time | 獲取時間 |
year | 獲取年份 |
month | 獲取月份 |
day | 獲取天 |
hour | 獲取小時 |
minute | 獲取分鐘 |
second | 獲取秒 |
dayofyear | 資料處于一年中的第幾天 |
weekofyear | 資料處于一年中的第幾周(新版使用 isocalendar().week) |
weekday | 資料處于一周中的第幾天(數字 周一為0) |
day_name() | 資料處于一周中的第幾天(英文 Monday) |
quarter | 資料處于一年中的第幾季度 |
is_leap_year | 是否為閏年 |
這里隨便選第 100 行的日期做示例,各個屬性的結果均以注釋的形式展示,
df['datetime'].dt.date[100]
# datetime.date(2021, 4, 11)
df['datetime'].dt.time[100]
# datetime.time(11, 50, 58, 995000)
df['datetime'].dt.year[100]
# 2021
df['datetime'].dt.month[100]
# 4
df['datetime'].dt.day[100]
# 11
df['datetime'].dt.hour[100]
# 11
df['datetime'].dt.minute[100]
# 50
df['datetime'].dt.second[100]
# 58
df['datetime'].dt.dayofyear[100]
# 101
df['datetime'].dt.isocalendar().week[100]
# 14
df['datetime'].dt.weekday[100]
# 6
df['datetime'].dt.day_name()[100]
# 'Sunday'
df['datetime'].dt.quarter[100]
# 2
df['datetime'].dt.is_leap_year[100]
# False
重采樣 resample()
重采樣分為 降采樣 和 升采樣 兩種,
降采樣指的是采樣的時間頻率低于原時間序列的時間頻率,同時來講就是一個聚合操作,看示例,下面獲取各季度的 count 列平均值,Q 代表 quarter 表示按季度采樣,
df.resample('Q',on='datetime')["count"].mean()

注意:此時的輸出的最大時間為06-30, 并不是實際資料中的 05-31, 但是并不影響計算,
升采樣與降采樣相反,指的是采樣的時間頻率高于原時間序列的時間頻率,相當于獲取更細緯度的時間資料,但這樣往往會造成資料中存在大量空值,實際用的不多,這里就不展開講解了,
DataFrame遍歷方式
iterrows() - 遍歷行(索引,列值序列)
按行進行遍歷,獲取行的索引與列值序列,速度較慢,直接看例子,
for index, row in df.iterrows():
print(index)
print(row)
print(row['name'])
print(row['age'])
break # 演示所用,只顯示一行

iteritems() - 遍歷(列名,值)
按列進行遍歷,獲取列名與該列的值,
for column, value in df.iteritems():
print(column)
print(value)
break # 演示所用,只顯示一行

itertuples() - 遍歷行 (索引,列值A,列值B…)
按行進行遍歷,獲取行的索引與列值,與 iterrows 的不同之處是索引與列值包含在一起,用 info[0] 獲取索引
for info in df.itertuples():
print(info[0])
print(info[1])
print(info[2])
break # 演示所用,只顯示一行

這就是本文所有的內容了,如果感徑訓不錯的話,? 記得三連支持哦!!!?
后續會繼續分享各種干貨,如果感興趣的話可以點個關注不迷路哦~,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/301530.html
標籤:python
上一篇:第一次專業記錄

