import pandas as pd
引言
原始的數(shù)據(jù)有時(shí)候是一串文字(過(guò)度聚合),有時(shí)候是分散在多個(gè)位置的分離文件(過(guò)于分散)。數(shù)據(jù)的預(yù)處理就是要把原始的數(shù)據(jù)拆分、組合、標(biāo)準(zhǔn)化,并將異常的數(shù)據(jù)剔除掉。在這個(gè)過(guò)程中,字符串的拆分與合并非常重要。python內(nèi)建函數(shù)可以實(shí)現(xiàn)簡(jiǎn)單字符串的拆分與合并(split與format函數(shù))。而re庫(kù)、pandas庫(kù)又提供了更加強(qiáng)大的數(shù)據(jù)預(yù)處理手段,能幫助我們運(yùn)用簡(jiǎn)單的代碼實(shí)現(xiàn)復(fù)雜的功能。建議在進(jìn)行數(shù)據(jù)處理的時(shí)候,將數(shù)據(jù)轉(zhuǎn)換為DataFrame格式,運(yùn)用pandas庫(kù)強(qiáng)大的功能庫(kù)進(jìn)行處理。
一、概括篇
Panel Data(面板數(shù)據(jù)),大部分類(lèi)型的底層數(shù)組都是numpy.ndarray
足以處理金融、統(tǒng)計(jì)、社會(huì)科學(xué)、工程等領(lǐng)域里的大多數(shù)典型用例
輕松直觀(guān)地處理帶標(biāo)簽數(shù)據(jù)和關(guān)系數(shù)據(jù)
為行和列設(shè)定標(biāo)簽
將不同格式的數(shù)據(jù)加載到 DataFrame 中
可以將不同的數(shù)據(jù)集合并到一起
與 NumPy 和 Matplotlib 集成
社區(qū)活躍
長(zhǎng)遠(yuǎn)目標(biāo):成為最強(qiáng)大、最靈活、可以支持任何語(yǔ)言的開(kāi)源數(shù)據(jù)分析工具
-
支持?jǐn)?shù)據(jù)類(lèi)型
對(duì) Numpy 類(lèi)型系統(tǒng)進(jìn)行了擴(kuò)充
用 object 存儲(chǔ)字符串
整數(shù)的默認(rèn)類(lèi)型為 int64,浮點(diǎn)數(shù)的默認(rèn)類(lèi)型為 float64
Pandas 數(shù)據(jù)類(lèi)型 數(shù)據(jù)結(jié)構(gòu)的特性
Pandas 用
NaN
(Not a Number)表示缺失數(shù)據(jù)
DataFrame 里的缺失值用np.nan
表示
借助 numexpr 與 bottleneck 支持庫(kù),pandas 可以加速特定類(lèi)型的二進(jìn)制數(shù)值與布爾操作支持 add()、sub()、mul()、div() 及radd()、rsub() 等方法執(zhí)行二進(jìn)制操作
二進(jìn)制比較操作的方法:
- 通用操作
創(chuàng)建
.copy()
淺復(fù)制,不改變?cè)紨?shù)據(jù)屬性
.dtypes
屬性
DataFrame:以 Series 形式返回每列的數(shù)據(jù)類(lèi)型
DataFrame.dtypes.value_counts()
用于統(tǒng)計(jì) DataFrame 里各列數(shù)據(jù)類(lèi)型的數(shù)量
select_dtypes(include =[], exclude=[])
基于dtype
選擇列數(shù)據(jù)類(lèi)型轉(zhuǎn)換
astype()
把一種數(shù)據(jù)類(lèi)型轉(zhuǎn)換為另一種,默認(rèn)返回的是復(fù)制數(shù)據(jù)df.astype('float32').dtypes
說(shuō)明:可以通過(guò)字典指定哪些列轉(zhuǎn)換為哪些類(lèi)型 {'Column': np.bool}
- 硬轉(zhuǎn)換
.to_numpy()
或numpy.asarray()
.to_numeric()
轉(zhuǎn)換為數(shù)值型
.to_datetime()
轉(zhuǎn)換為 datetime 對(duì)象
.to_timedelta()
轉(zhuǎn)換為 timedelta 對(duì)象- 軟轉(zhuǎn)換
數(shù)據(jù)有時(shí)存儲(chǔ)的是正確類(lèi)型,但在保存時(shí)卻存成了 object 類(lèi)型,此時(shí),用DataFrame.infer_objects()
與Series.infer_objects()
方法即可把數(shù)據(jù)軟轉(zhuǎn)換為正確的類(lèi)型
- 排序/遍歷/統(tǒng)計(jì)
排序
- 按索引排序
Series.sort_index()
DataFrame.sort_index()
- 按值排序
Series.sort_values()
DataFrame.sort_values()
參數(shù) by 用于指定按哪列排序(一列或多列數(shù)據(jù))- 按索引與值排序
- 按多重索引的列排序
遍歷(迭代)
Series 迭代時(shí)被視為數(shù)組;支持字典式的
items()
方法, (Index, 標(biāo)量值)元組
DataFrame 列標(biāo)簽;支持字典式的items()
方法,(Columns, Series)元組
統(tǒng)計(jì)
pd.Series.value_counts()
pd.DataFrame.value_counts()
廣播
多維(DataFrame)與低維(Series)對(duì)象之間的廣播機(jī)制。
重點(diǎn)關(guān)注輸入的 Series:通過(guò) axis 關(guān)鍵字,匹配 index 或 columns 即可調(diào)用這些函數(shù)函數(shù)應(yīng)用(作為函數(shù)的參數(shù))
用哪種方法取決于操作的對(duì)象是DataFrame 或 Series ,是行或列,還是元素
- 表級(jí)函數(shù)應(yīng)用
通過(guò)鏈?zhǔn)秸{(diào)用函數(shù)時(shí),最好使用pipe()
方法- 行列級(jí)函數(shù)應(yīng)用
apply()
方法可以沿著 DataFrame 的軸應(yīng)用任何函數(shù),比如,描述性統(tǒng)計(jì)方法,該方法支持 axis 參數(shù)- 聚合 API
agg()
與transform()
快速、簡(jiǎn)潔地執(zhí)行多個(gè)聚合操作- 元素級(jí)函數(shù)應(yīng)用
并非所有函數(shù)都能接受 Numpy 數(shù)組,DataFrame 的applymap()
及 Series 的map()
,支持任何接收單個(gè)值并返回單個(gè)值的 Python函數(shù)。
舉例:df[Column].apply(lambda x: x.split()[0])
pd.Series本身沒(méi)有.split()
,但可以針對(duì)每個(gè)數(shù)據(jù)進(jìn)行函數(shù)操作
二、Series篇
Series與Numpy中的一維array類(lèi)似,二者與Python基本的數(shù)據(jù)結(jié)構(gòu)List也很相近
區(qū)別是:List中的元素可以是不同的數(shù)據(jù)類(lèi)型,而 Array 和 Series 中則只允許存儲(chǔ)相同的數(shù)據(jù)類(lèi)型,這樣可以更有效的使用內(nèi)存,提高運(yùn)算效率
和 NumPy ndarray 的區(qū)別:
- 每個(gè)元素分配索引標(biāo)簽(label 即index)
- 可以存儲(chǔ)不同類(lèi)型的數(shù)據(jù)
- 數(shù)據(jù)結(jié)構(gòu)的特性
+可變
+帶標(biāo)簽的一維數(shù)組,可存儲(chǔ)整數(shù)、浮點(diǎn)數(shù)、字符串、Python 對(duì)象等類(lèi)型的數(shù)據(jù)(軸標(biāo)簽統(tǒng)稱(chēng)為索引)
+類(lèi)似多維數(shù)組:操作與 ndarray 類(lèi)似,支持大多數(shù) NumPy 函數(shù),還支持索引切片
+類(lèi)似字典:必須提供索引
- 創(chuàng)建
- 通過(guò)list創(chuàng)建
pd.Series([list])
pd.Series(data = [30, 6, 'Yes', 'No'], index = ['eggs', 'apples', 'milk', 'bread'])- 特殊:時(shí)間序列
pd.data_range()
Series 時(shí)間序列
- 查/改/增/刪
屬性
.shape
.ndim
.size
.values
.index
查
- 訪(fǎng)問(wèn)
Series['label/index']
+.loc
標(biāo)簽索引
+.iloc
數(shù)值索引- 判斷
in
改
- 索引重置與更換
reindex()
reindex_like()
用align對(duì)齊多個(gè)對(duì)象- 索引重命名
.Series.rename()
支持按不同的軸基于映射(字典或 Series)調(diào)整標(biāo)簽- 數(shù)據(jù)平移
pd.Series().shift(N)
向下平移N行
刪
Series.drop(label, inplace=False)
與 reindex 經(jīng)常配合使用,該函數(shù)用于刪除軸上的一組標(biāo)簽
- 排序/遍歷/統(tǒng)計(jì)
排序 @概括篇-排序
- 搜索排序
Series.searchsorted()
這與numpy.ndarray.searchsorted()
的操作方式類(lèi)似- 最大值與最小值
.nsmallest()
與.nlargest()
方法,本方法返回 N 個(gè)最大或最小的值
遍歷
.items()
(Index, 標(biāo)量值)元組
- 特性:數(shù)學(xué)運(yùn)算(參考ndarray)
與單個(gè)數(shù)字
Series + 2
Series - 2
Series * 2
乘法對(duì)字符串可行
Series / 2
除法對(duì)字符串不可行數(shù)學(xué)函數(shù)
np.exp(Series)
np.sqrt(Series)
np.power(Series,2)
- 補(bǔ)充:小技巧
結(jié)合布爾運(yùn)算
list[True]
最后一個(gè)數(shù)
list[False]
第一個(gè)數(shù)
close_planets = time_light[[False, True, True, False, False]]
只輸入True對(duì)應(yīng)的兩個(gè)元素(第一個(gè)[]表示index,第二個(gè)[]表示列表)
注意:元素個(gè)數(shù)和True/False個(gè)數(shù)必須匹配結(jié)合字符串方法
pd.Series.str.lower()
三、DataFrame篇
像 Series 一樣, DataFrame 的 values 屬性返回一個(gè)包含在 DataFrame 中的數(shù)據(jù)的二維 ndarray(Pandas大部分?jǐn)?shù)據(jù)類(lèi)型的底層是ndarray)
數(shù)據(jù)結(jié)構(gòu)的特性
帶標(biāo)簽的行和列的二維數(shù)據(jù)結(jié)構(gòu),可以存儲(chǔ)很多類(lèi)型的數(shù)據(jù)(類(lèi)似Excel的電子表格)創(chuàng)建
- 用 Series字典或字典生成
dict = {'key1': pd.Series([]), index = [], 'key2': pd.Series([]), index = []}
df = pd.DataFrame(dict)
+列:字典的key
+行:字典的value,也就是Series的index(Series的Data作為DataFrame的數(shù)據(jù))
沒(méi)有Series.index時(shí),從0開(kāi)始計(jì)數(shù)作為行標(biāo)簽
- 用多維數(shù)組字典、列表字典生成
dict = {'key1':[], 'key2': []}
df = pd.DataFrame(dict)
+列:字典的key
+行:對(duì)應(yīng)沒(méi)有Series.index的情況,從0開(kāi)始計(jì)數(shù)作為行標(biāo)簽(列表作為DataFrame的數(shù)據(jù))
多維字典生成DataFrame
查看各列的數(shù)據(jù)類(lèi)型- 用結(jié)構(gòu)多維數(shù)組或記錄多維數(shù)組生成
- 用嵌套字典的列表生成
list = [{'bikes': 20, 'pants': 30, 'watches': 35}, {'watches': 10, 'glasses': 50, 'bikes': 15, 'pants':5}]
df = pd.DataFrame(list)
+列:所有的key
+行:每個(gè)字典對(duì)應(yīng)一行,但沒(méi)有行標(biāo)簽,自動(dòng)生成數(shù)字標(biāo)簽(數(shù)據(jù)就是字典key對(duì)應(yīng)的值)
嵌套字典的列表用嵌套字典的元組生成
嵌套字典的元組- 用ndarray創(chuàng)建
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
df1=pd.DataFrame(a,index=['row0','row1','row2'],columns=list('ABC'))
- 其余
DataFrame.from_dict
接收字典組成的字典或數(shù)組序列字典,并生成 DataFrame
DataFrame.from_records
構(gòu)建器支持元組列表或結(jié)構(gòu)數(shù)據(jù)類(lèi)型(dtype)的多維數(shù)組
- 查/改/增/刪
屬性
.index
.columns
.shape
(行, 列)
.ndim
秩
.size
行*列==元素
.values
數(shù)據(jù)data(Series.values或DataFrame.values)
查
- 訪(fǎng)問(wèn) (切片操作適用)
df[Column][Row/Index]
df.loc[:, [columns]]
標(biāo)簽索引,選擇列
df.iloc[2,:]
數(shù)值索引,查詢(xún)第二行
df.at[row, column]
快速定位DataFrame的元素
df.iat[x,x]
數(shù)值索引,快速定位
.ix[]
先用loc的方式來(lái)索引,索引失敗就轉(zhuǎn)成iloc(將被剔除,盡量不要使用)
- 布爾(邏輯判斷)
indices = np.where(np.isnan(a))
獲取索引值
indices = np.where(pd.isnull(a))
兩者等價(jià)
np.where(np.isnan(df))
返回tuple 第一個(gè)ndarray表示行的數(shù)值索引,第二個(gè)ndarray表示列的數(shù)值索引
numpy.take(a, indices, axis=None, out=None, mode='raise')
提取指定索引位置的數(shù)據(jù),并以一維數(shù)組或者矩陣返回(主要取決axis)
根據(jù)indices訪(fǎng)問(wèn)數(shù)據(jù)
df.loc[(df['C']>2) & (df['D']<10) ]
df.loc[df['C'].isin([3,5,6])]
df['D'] = np.where(df.A<3, 1, 0)
如果A<3,D為1;如果A≥3,D為0
- 選取部分表格
pd.DataFrame(df, index = ['glasses', 'bike'], columns = ['Alice'])
- 選取某列含有特殊數(shù)值的行
df.loc[[index]]
df[df.Column > 0]
df1[df1['A'].isin([1])]
選取df1中A列包含數(shù)字1的行
df1=df1[~df1['A'].isin([1])]
通過(guò)~取反,選取不包含數(shù)字1的行
df.[df.index.isin(newindex)]
- 選取某行含有特殊數(shù)值的列
df[[Columns]]
cols=[x for i,x in enumerate(df2.columns) if df2.iat[0,i]==3]
df2=df2[cols]
改
df.T
轉(zhuǎn)置
- 數(shù)據(jù)精度設(shè)置
pd.set_option('precision', 1)
小數(shù)點(diǎn)后一位
- 修改列標(biāo)簽
df.columns = ['a', 'b']
- 修改行標(biāo)簽
.reset_index
df.set_index(Column)
將某列(的值)作為行標(biāo)簽/索引(常把日期/時(shí)間列作為行索引)
store_items =store_items.set_index('pants')
df.index = [index + '_5m' for index in df.index]
直接修改:?jiǎn)栴}默認(rèn)的index是pandas.indexes.base.Index,這個(gè)格式可能會(huì)默認(rèn)index里面數(shù)據(jù)的長(zhǎng)度是確定的,導(dǎo)致加_5m后綴失敗
關(guān)鍵:修改index的類(lèi)型list(df.index) list元素可變
- 萬(wàn)能
df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
df.reindex(index=[], columns=[])
增
- 添加標(biāo)簽/索引
pd.DataFrame(data, index = ['label 1', 'label 2', 'label 3'])
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
建立行索引
建立行索引- 添加新的列
df[new_column] = df[old_column1] + df[old_column2]
dataframe.insert(loc,label,data)
- 添加新的行
首先創(chuàng)建新的 Dataframe,然后將其附加到原始 DataFrame 上
pd.DataFrame(new_data, index = ['store 3'])
新行附加到 DataFrame 后,列按照字母順序排序表格合并
pandas中提供了大量的方法能夠輕松對(duì)Series,DataFrame和Panel對(duì)象進(jìn)行不同滿(mǎn)足邏輯關(guān)系的合并操作
df1.join(df2, axis=, join='outer')
pd.merge(df1, df2, on=[keys], suffixes=[], how='inner')
suffixes表示合并后列名的后綴
pd.concat([df1, df2, df3], axis = )
.append()
只有縱向合并(添加新的數(shù)據(jù))
注意:兩種方式均可
1)pd.func(data1, data2)
2)data1.func(data2)
- 堆疊stack
df.stack()
df.unstack(0)
0表示第一行索引展開(kāi)成列
刪
df2=df2.drop(cols,axis=1)
利用drop方法將含有特定數(shù)值的行/列(指定axis)刪除
del df[Column]
df.pop(Column)
僅允許我們刪除列
- 排序/遍歷/統(tǒng)計(jì)
排序 @概括篇-排序
遍歷(迭代)
items()
(Columns, Series)元組統(tǒng)計(jì)
empty()
、any(iterable)
、all()
、bool()
把數(shù)據(jù)匯總簡(jiǎn)化為布爾值(empty:驗(yàn)證元素是否為空)
df.head()
df.tail()
df.isnull()
返回一個(gè)大小和df一樣的布爾型DataFrame,結(jié)合.sum()df.isnull().sum().sum()
第一個(gè) sum()返回一個(gè) Pandas.Series
df.count()
df.describe()
df.value_counts()
df.unique()
- 統(tǒng)計(jì)學(xué)函數(shù)
df.mean()
df,median()
df.max()
df.std()
df.corr()
相關(guān)系數(shù)矩陣
df..cov()
協(xié)方差矩陣
df.corrwith()
計(jì)算其列或行跟另一個(gè)Series或DataFrame之間的相關(guān)系數(shù)
統(tǒng)計(jì)函數(shù)- 分組匯總 .groupby()
data.groupby(['Year'])['Salary'].sum()
data.groupby(['Name'])['Salary'].sum()
data.groupby(['Year', 'Department'])['Salary'].sum()
data.groupby(['Year'])['Salary'].mean()
pandas.melt(df, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)
保留指定列,其他列打散:類(lèi)似匯總統(tǒng)計(jì)的逆操作
- 數(shù)據(jù)透視表
pd.pivot_table(df, values=, index=[], columns=[])
- 特性:時(shí)間序列
pd.date_range(, periods=, freq=)
創(chuàng)建時(shí)間序列數(shù)據(jù),也可以作為后續(xù)的行索引index freq='S'秒, 'D'天, 'M'月, 'Q-NOV'季度
df.rolling(N).mean()
計(jì)算 N 天期限的滾動(dòng)均值
pd.Series.resample()
重采樣
pd.Series.tz_localize('UTC')
時(shí)區(qū)
pd.Series.tz_localize('UTC').tz_convert('US/Eastern')
時(shí)區(qū)轉(zhuǎn)換
pd.Series.to_period()
pd.Series.to_timestamp()
(pd.period_range.asfreq('M', 'end')).asfreq('H', 'start')
說(shuō)明:+9 表示09:00
- 特性:數(shù)據(jù)處理相關(guān)操作
數(shù)學(xué)函數(shù)
df.sub()
減法數(shù)據(jù)整理與清洗
- 快速檢查NaN
df.isnull().any()
np.nanmean(ndarray, axis=0)
屬于Numpy中不包括NaN按axis取平均值(看作沒(méi)有NaN)- 對(duì)NaN值的處理
df.dropna(axis= , inplace=False, how='any')
刪除
df.fillna(0)
替換
df.fillna(method = 'ffill', axis=0)
針對(duì)行進(jìn)行前向填充
df.fillna(method = 'backfill', axis=0)
針對(duì)行進(jìn)行后向填充
df.interpolate(method = 'linear', axis)
linear 插值
df.replace(a, b)
.fill_value()
處理缺失值- 數(shù)據(jù)整理:進(jìn)入特定分組
pd.cut()
1). 等距劃分分組 pd.cut(ndarray, num) num表示劃分的組數(shù)
2). 設(shè)定分組,使得每個(gè)數(shù)據(jù)點(diǎn)歸入到相應(yīng)分組
pd.cut()
pd.melt(df, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)
說(shuō)明:將目標(biāo)列“融化”,或合并,或拆解,形成新的特征列(適合單個(gè)個(gè)體多屬性:統(tǒng)一只羅列一個(gè)屬性)
+df:要處理的數(shù)據(jù)集。
+id_vars:不需要被轉(zhuǎn)換的列名。
+value_vars:需要轉(zhuǎn)換的列名,如果剩下的列全部都要轉(zhuǎn)換,就不用寫(xiě)了。
+var_name和value_name是自定義設(shè)置對(duì)應(yīng)的列名
+col_level :如果列是MultiIndex,則使用此級(jí)別
@示例:type1和type2合并成一個(gè)類(lèi)型
#新的列名type_level,相應(yīng)的值作為新的列type
#要改變的列
type_cols = ['type_1','type_2']
#不改變的列
non_type_cols = pokemon.columns.difference(type_cols)
pkmn_types = pokemon.melt(id_vars = non_type_cols, value_vars = type_cols,
var_name = 'type_level', value_name = 'type').dropna()
pkmn_types.head()
分類(lèi)數(shù)據(jù)
df[Column].astype("category")
df[Column].cat.categories = []
重命名分類(lèi)名稱(chēng)
df[Column].cat.categories.cat.set_categories([])
在重命名的基礎(chǔ)上添加新的類(lèi)別名稱(chēng)
- 特性:數(shù)據(jù)IO
ndarray讀寫(xiě)效率最高,但最費(fèi)硬盤(pán)空間,比如np.load()
,np.save()
,csv其次。比如pd.Dataframe.to_csv()
,pd.load_csv()
。
txt讀寫(xiě),當(dāng)然也可以很快,但是需要頻繁的split,對(duì)格式規(guī)范的數(shù)據(jù)比較麻煩。
至于簡(jiǎn)單的excel和word,可以用xlrd,xlwt來(lái)操作
numpy的速度比dataframe快,其次對(duì)于txt或者csv的數(shù)據(jù),用map,reduce,filter三個(gè)函數(shù),自己寫(xiě)好function往里面套就行,稍微有點(diǎn)麻煩,但最重要的是這樣可以并行化,寫(xiě)好的東西可以直接放到map+reduce上跑,尤其是對(duì)于數(shù)據(jù)量比較大的時(shí)候。這樣的寫(xiě)法另外一個(gè)好處是轉(zhuǎn)向pyspark時(shí)非常的方便
CSV (comma-separated values)
df.to_csv('data/foo.csv')
pd.read_csv(filepath)
HDF5
df.to_hdf('data/foo.h5', 'df')
pd.read_hdf('data/foo.h5', 'df')
Excel
df.to_excel('data/foo.xlsx', sheet_name='Sheet1')
pd.read_excel('data/foo.xlsx', 'Sheet1',index_col=None, na_values=['NA'])
pickle模塊
持久化:將對(duì)象以文件的形式存放在磁盤(pán)
.to_pickle('student.pickle')
特性:廣播機(jī)制 @概括篇
特性:函數(shù)應(yīng)用(作為函數(shù)的參數(shù)) @概括篇
補(bǔ)充:小技巧
0-1變量比例統(tǒng)計(jì)
np.sum(df['Column']) /df.shape[0]
四、拓展
- 模塊pandas-datareader