0、常用
1)讀寫
①從不同文本文件中讀取數據的函數,都是read_xxx的形式;寫函數則是to_xxx;
②對前n行感興趣,或者用於檢查讀進來的數據的正確性,用head(n)方法;類似的,后n行,用tail(n)——如果不寫參數n,將會是5行;信息瀏覽可以用info()方法;
③檢查各列的類型,用dtypes屬性。
2)取子集
①這一部分的內容與numpy的切片、索引部分很類似;
②可以通過shape屬性查看DataFrame與Series的尺寸;
③如果要查看其中的若干列,索引為這些列名的list,不能單獨直接寫列名
person_df[['Name','Age']]#列名的list,√
person_df['Name','Age']#直接寫列名,×
④篩選特定行,類似numpy中的布爾索引
df[df['Age']>35] | df中Age大於35的行 |
df[func(df['Age'])] | df中對Age進行函數func后返回True的行 |
如果,直接用索引值df['Age']>35,則返回一個與df['Age']相同大小的Series,只是相關的值代之以True或False
3)DataFrame
DataFrame是一個2維的數據結構,每行可以存儲不同的數據結構。實際上,用Excel表可以更容易理解,每列則表示一個Series(Series是另一種pandas數據結構,一個Series中的數據為同一種類型;此外,Series還有個Name屬性),同時有一個列標簽;每行也有一個行標簽,行標簽總是數字0、1、2...。
下面我們顯式的構造一個DataFrame,由於一個DataFrame有多個屬性列即多個Series。所以構建時先建立一個dict,這個dict的key分別是這些Series的名,value是所有Series在該屬性下的value的list,注意順序一定要一致:
importpandasaspd person={ 'Name':["Braund,Mr.OwenHarris", "Allen,Mr.WilliamHenry", "Bonnell,Miss.Elizabeth",], 'Age':[22,35,58], 'Sex':["male","male","female"], } person_df=pd.DataFrame(person) person_df NameAgeSex 0Braund,Mr.OwenHarris22male 1Allen,Mr.WilliamHenry35male 2Bonnell,Miss.Elizabeth58female
如果對某列感興趣,可以通過列名(DataFrame[ 列名 ])的方式直接索引,就像查找dict某個key一樣
person_df['Age'] 0 22 1 35 2 58 Name:Age,dtype:int64
關於DataFrame的各項屬性及方法,可以看pandas(三);Series的部分可以看pandas(四)
4)繪圖
①直接對整個DataFrame用方法plot,可以得到所有數值列隨Index列變化的折線圖;
②對某一列用plot,可以得到該列隨Index變化的折線圖;
③其他的散點圖、箱型圖,都與matplotlib的相關方法用法相似,而且可以直接從DataFrame的相關方法(見pandas(三))中找到。
④所有plot.*方法的返回值都是Matplotlib對象
5)對列的操作
①對原列的數據進行運算,得到新列的數據,並保存為新列
DataFrame['new'] = DataFrame['old'] * 2
這樣就會在最右邊生成一個新列'new',其值是'old'列的兩倍
②用兩列進行運算,結果保存為新列
DataFrame['new'] = DataFrame['old1'] / DataFrame['old2']
③給列重命名
DataFrame_rename = DataFrame.rename( columns={ 'old1':'new1', 'old2':'new2', 'old3':'new3' } )
行列Index均可通過rename重命名,都是dict的格式;
此外,也可以通過傳入一個函數,來實現對所有的行列Index進行統一處理,例如:把所以列名的英文小寫
DataFrame_rename = DataFrame.rename(columns = str.lower)
6)統計函數
①既可以對整個DataFrame的所有數據列進行統計,也可以只對其中的部分列
對部分列進行統計的用法:
DataFrame[ 列名list ].describe()
air_quality=pandas.read_csv('air_quality_no2.csv') air_quality.describe() station_antwerp station_paris station_london count 95.000000 1004.000000 969.000000 mean 25.778947 27.740538 24.777090 std 12.682019 15.285746 11.214377 min 7.500000 0.000000 0.000000 25% 16.750000 16.500000 19.000000 50% 23.000000 24.150000 25.000000 75% 34.500000 35.925000 31.000000 max 74.500000 97.000000 97.000000
air_quality['station_antwerp'].describe() count 95.000000 mean 25.778947 …… 50% 23.000000 75% 34.500000 max 74.500000 air_quality[['station_antwerp','station_paris']].describe() station_antwerp station_paris count 95.000000 1004.000000 mean 25.778947 27.740538 …… 50% 23.000000 24.150000 75% 34.500000 35.925000 max 74.500000 97.000000
②聚簇統計——先根據某列中的數值分類,再對每類數據進行分類
方法:
DataFrame.groupby(分類依據的列).describe()
DataFrame[ 列名List ].groupby( 分類所依據的列 ).describe() #①列名List中必須包含分類列和需要進行統計的列
#②如果是對整個DataFrame用groupby,則會對除分類列外的所有列進行統計分析
#③分類列可以是多列,此時會分為 這兩列類別之積 的類別數
例如:統計不同性別(性別列為'Sex')的年齡數據
DataFrame[ ['Sex','Age'] ].groupby('Sex').describe()
統計每種類別中的數據數量:a.按類別中的樣本數量從大到小;b、按類別名從小到大
a.將統計函數變為value_counts()
b.統計函數為count()
titanic["Pclass"].value_counts() Out[12]: 3 491 1 216 2 184 Name: Pclass, dtype: int64 titanic.groupby("Pclass")["Pclass"].count() Out[13]: Pclass 1 216 2 184 3 491 Name: Pclass, dtype: int64
7)重組織DataFrame的表格數據分布(reshape)
①按某列數值大小排序:sort_values(by= 列名 或 列名List)
DataFrame.sort_values(by='Age')
②從長數據到寬數據(單獨觀察某一列的數據):pivot(見第二部分pandas(二))
8)表格連接
concat(豎向或者橫向堆積)與merge(類似數據庫的連接)
9)時間數據
將輸入的時間文本轉化為datetime類型,pd.to_datetime
1、讀寫函數
正如在0章2節讀寫部分所說,讀函數的格式都是read_xxx,寫函數的格式都是to_xxx,不過需要注意的是,read_xxx是pandas的函數,調用方法為pd.read_xxx;to_xxx是DataFrame的方法,用法為DataFrame.to_xxx,相當於直接把某個DataFrame給保存到某個文件中
函數有很多,基本上所有的表格類型數據都可以讀進來,有興趣的可以去pandas官方文檔:input/output自己找需要的,下面只介紹read_csv和read_excel
1.1、read_csv
學習自:詳解pandas的read_csv方法 - 古明地盆 - 博客園
CSV文件 列與列間的分隔符是逗號,行與行間的分隔符是'\n'
用法
pandas.read_csv( filepath_or_buffer, sep=',', delimiter=None, delim_whitespace=True, header='infer', names=None, index_col=None, usecols=None, mangle_dupe_cols=True, dtype=None, converters=None, true_values=None, false_values=None, skiprows=None, skipfooter=0, nrows=None, low_memory=True, na_values=None, na_filter=True, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, date_parser=None, iterator=False, compression='infer', encoding=None, error_bad_lines=True, warn_bad_lines=True, )
參數
官方文檔中參數多達50個(上文沒給全),但也不是每個每次都用得上,下面只說那些自己覺得重要的
參數 | 類型 | 默認值 | 說明 |
filepath_or_buffer | str | 文件名 | |
sep | str | ',' | 分隔符;如果文件列與列間以\t分隔,那么該參數就可以設置為'\t' |
delimiter | str | None | sep的別名 |
delem_whiterspace | bool | True | 分隔符為空白字符,包括空格,\t等 |
header | int或int list | infer | 列索引行。默認第0行; 如果同時給出header和names,則不會默認用第0行而需要手動設置header=0,需要指定header作為索引行;這時會用names作為列名,用除header之外的行作為數據; 如果header=None,則列名就為names,數據為全部 |
names | list | 給讀入的列命名(List大小和usecols相同) | |
index_col | int | 索引列,如果為None,則會自動生成0,1,2,...的標簽列 | |
usecols | list | 列的子集。如果不是每列都用得上,就可以只挑選其中的若干列,可以是列索引的list,比如[0,1,2]表示前3列,也可以是列名的list,比如['name','age'] | |
mangle_dupe_cols | bool | True | 有同名列時,會在重名列名后加.n,n為重名列的序號 |
dtype | {'列名1':type,...} | 指定相關列的類型 | |
converters | {'列名1':func1,...} | 對相關列的值進行轉化,舉例,如果想讓id全部加10,該項可以這樣寫(由於該參數在使用時默認列類型是string,所以處理數字類型時,需要用類型轉換函數) pd.read_csv( 'data.csv', converters={"id":lambdax:int(x)+10} ) |
|
true_values與false_values | list | 哪些值(true_values中說明)被替換為True,哪些值(false_values中說明)被替換為False,只有當某一列的所有數據都在true_values+false_values中時,該列的數據才會被替換為True或False | |
skiprows | int,list | 如果是list,過濾掉哪幾行;如果是int,過濾掉前幾行 先過濾再確定表頭 |
|
skipfooter | int | 0 | 過濾掉最后幾行 |
n_rows | int | 讀進來多少行(讀大文件時有用) | |
low_memory | bool | True | 默認為True,意思是讀取數據時,分塊讀取,可以減小類型錯誤,但會導致長耗時 設置為False,一次全部讀入內存,耗時短,有可能導致內存溢出 |
na_values | str,list | 哪些值被認定為NaN | |
na_filter | bool | True | 缺值是否視為NaN |
skip_blank_lines | bool | True | 是否過濾掉空行,如果False,則將空行視為False |
parse_dates | bool或int list或name list | 如果是True,就把Index列解析為datetime 如果是另外兩種:指定某些列為Date類型,配合參數date_parse使用 |
|
infer_datetime_format | bool | False | 如果設置為True且parse_dates存在,則會自動嘗試解析這些Date string |
date_parser | function | 解析之前標注的日期列的函數 | |
iterator | bool | False | 如果為True,則返回一個TextFileReader對象,以便逐塊處理文件。當文件很大無法一次性讀入時,很有用 |
compression | ['infer','gzip','zip',...] | infer | 直接讀取壓縮文件中的csv文件 |
encoding | 字符集編碼類型 | ||
error_bad_lines與warn_bad_lines | bool | True | 刪除格式錯誤的行 |
例子
data = pd.read_csv(csv_name, encoding='GBK', usecols=[1, 5],
names=['Time', 'Changes'],header=0)
由於原CSV文件存在中文,所以讀入時encoding='GBK',usecols指明實際讀入哪幾列,下標從0開始,names為這些列指定index,如果指定了names用作索引,就需要寫header=0,表明以第0行為索引行,否則會導致將原來的索引行讀入進來當做數據行。
1.2、read_excel
用法
pandas.read_excel( io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, dtype=None, converters=None, true_values=None, false_values=None, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, parse_dates=False, date_parser=None, mangle_dupe_cols=True, )
參數
這里只說前兩個參數io與sheet_name,其他的參數與read_csv相同,就不再贅述
參數 | 類型 | 默認值 | 說明 |
io | 文件URL,支持xls與xlsx | ||
sheet_name | str,int,list,None | 0 | str:表的名字 int:表的索引 list:多個表 None:全部表 |
如果設置第二個參數sheet_name=None,就會讀入全部的sheet,可以通過data[ sheet_name ]來訪問每一個sheet:
data = pd.read_excel( excel_name , sheet_name = None ) data['sheet1'] data['sheet2']
可以通過data.keys()得到所有sheet名:再通過
for sheet in list(data.keys()): ...
data[sheet]訪問各sheet,每個sheet都是一個DataFrame
1.3、to_csv
用法
DataFrame.to_csv( path_or_buf=None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=True, mode='w', encoding=None, compression='infer', chunksize=None, date_format=None, errors='strict', )
參數
參數 | 類型 | 默認值 | 說明 |
path_of_buf | str | None | 輸出文件名 |
sep | 長度為1的str | ',' | 列與列間隔符 |
na_rep | str | '' | 缺省值填充字符串 |
float_format | str | None | 以格式化字符串的形式給出浮點數的形式,類似'%.2f'就是保留兩位小數 |
columns | list | 寫入哪些列 | |
header | bool,str list | True | 如果是bool,表示是否寫入索引行 如果是str list,表示寫入時各列的列名(即索引行) |
index | bool | True | 是否寫入索引列 |
mode | str | 'w' | python write mode,除了'w'外還有'a'追加 |
encoding | 編碼格式 | ||
compression | str | 是否壓縮為某種格式 | |
chunksize | int , None | 一次寫多少行 | |
date_format | str | None | 格式化字符串的形式給出date類型的形式 |
errors | str | 'strict' | 同open()函數中的errors參數的用法,忽略編碼錯誤用'ignore' |
1.4、to_excel
用法
DataFrame.to_excel( excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True, freeze_panes=None, storage_options=None )
參數
參數 | 類型 | 默認值 | 說明 |
excel_writer | str、ExcelWrite對象 | 輸出文件名 | |
sheet_name | str | 'Sheet1' | 表名 |
na_rep | str | '' | 缺省值的填充 |
float_format | str | 參照該格式將String轉化為float數字類型 | |
columns | sequence或str list | 寫入的列 | |
header | bool或list of str | True | 是否寫入索引行 如果是str list,表示寫入時各列的列名(即索引行) |
index | bool | True | 是否寫入索引列 |
index_label | str或sequence | 索引列的列名 | |
startrow | int | 0 | 起始行 |
startcol | int | 0 | 起始列 |
merge_cells | bool | True | 將有着多行和多列索引的單元格合並 |
encoding | str | 編碼格式,只用於xlwt文件,其他的都是unicode編碼 | |
inf_rep | str | 'inf' | 無窮大的填充 |
verbose | bool | True | 日志 |
freeze_panse | 有兩個int的tuple | 截止行與列(截止單元格) | |
storge_option | dict |
如果想保存到一個Excel中的多個表中,那么參數excel_writer就不能是單純的excel文件名,而應該是ExcelWriter對象,就像下邊這樣:
import pandas as pd excel_writer = pd.ExcelWriter(path, engine='openpyxl') for i in range(30):#生成30個sheet data = pd.DataFrame(...) data.to_excel(excel_writer,f'sheet{i}')#保存為sheet0 sheet1 ... excel_writer.close()
如果以前就有Excel文件和多個表,希望在這些表之后添加新表,可以看:Pandas:to_excel時如何不覆蓋之前的Excel表 - ShineLe - 博客園