很多人都分不清Numpy,Scipy,pandas三個庫的區別。
在這里簡單分別一下:
- NumPy:數學計算庫,以矩陣為基礎的數學計算模塊,包括基本的四則運行,方程式以及其他方面的計算什么的,純數學;
- SciPy :科學計算庫,有一些高階抽象和物理模型,在NumPy基礎上,封裝了一層,沒有那么純數學,提供方法直接計算結果; 比如:
- 做個傅立葉變換,這是純數學的,用Numpy;
- 做個濾波器,這屬於信號處理模型了,用Scipy。
- Pandas:提供名為DataFrame的數據結構,比較契合統計分析中的表結構,做數據分析用的,主要是做表格數據呈現。
目前來說,隨着Pandas更新,Numpy大部分功能已經直接和Pandas融合了。
如果想了解Numpy的話,可點擊閱讀《Python之Numpy的基礎及進階函數(圖文)》。
但如果你不是純數學專業,而且想做數據分析的話,嘗試着從 Pandas 入手比較好。
接下來講Pandas。
1數據結構
- Series:一維數組,與Numpy中的一維array類似。
- Time- Series:以時間為索引的Series。
- DataFrame:二維的表格型數據結構。可以將DataFrame理解為Series的容器。
- Panel :三維的數組,可以理解為DataFrame的容器。
# 導入別名 import pandas as pd pd.Series([1,2,3,4])
2數據讀取
2.1 csv文件讀取
read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=False, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, skip_footer=0, doublequote=True, delim_whitespace=False, as_recarray=False, compact_ints=False, use_unsigned=False, low_memory=True, buffer_lines=None, memory_map=False, float_precision=None)
- filepath_or_buffer:文件路徑,建議使用相對路徑
- header: 默認自動識別首行為列名(特征名),在數據沒有列名的情況下 header = none, 還可以設置為其他行,例如 header = 5 表示索引位置為5的行作為起始列名
- sep: 表示csv文件的分隔符,默認為','
- names: 表示設置的字段名,默認為'infer'
- index_col:表示作為索引的列,默認為0-行數的等差數列。
- engine:表示解析引擎,可以為'c'或者'python'
- encoding:表示文件的編碼,默認為'utf-8'。
- nrows:表示讀取的行數,默認為全部讀取
# 讀取csv,參數可刪 data = pd.read_csv('./data/test.csv',sep = ',',header = 'infer',names = range(5,18),index_col = [0,2],engine = 'python',encoding = 'gbk',nrows = 100)
# 讀取csv,參數可刪 data = pd.read_table('./data/test.csv',sep = ',',header = 'infer',names = range(5,18),index_col = [0,2],engine = 'python',encoding = 'gbk',nrows = 100)
2.2Excel 數據讀取
read_excel(io, sheetname=0, header=0, skiprows=None, skip_footer=0, index_col=None, names=None, parse_cols=None, parse_dates=False, date_parser=None, na_values=None, thousands=None, convert_float=True, has_index_names=None, converters=None, dtype=None, true_values=None, false_values=None, engine=None, squeeze=False, **kwds)
- io:文件路徑+全稱,無默認
- sheetname:工作簿的名字,默認為0
- header: 默認自動識別首行為列名(特征名),在數據沒有列名的情況下 header = none, 還可以設置為其他行,例如 header = 5 表示索引位置為5的行作為起始列名
- names: 表示設置的字段名,默認為'infer'
- index_col:表示作為索引的列,默認為0-行數的等差數列
- engine:表示解析引擎,可以為'c'或者'python'
data = pd.read_excel('./data/test.xls',sheetname='原始數據',header = 0,index_col = [5,6])
2.3數據庫數據讀取
- read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=None)
- sql:表示抽取數據的SQL語句,例如'select * from 表名'
- con:表示數據庫連接的名稱
- index_col:表示作為索引的列,默認為0-行數的等差數列
- read_sql_table(table_name, con, schema=None, index_col=None, coerce_float=True, parse_dates=None, columns=None, chunksize=None)
- table_name:表示抽取數據的表名
- con:表示數據庫連接的名稱
- index_col:表示作為索引的列,默認為0-行數的等差數列
- columns:數據庫數據讀取后的列名。
- read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)
- sql:表示抽取數據的表名或者抽取數據的SQL語句,例如'select * from 表名'
- con:表示數據庫連接的名稱
- index_col:表示作為索引的列,默認為0-行數的等差數列
- columns:數據庫數據讀取后的列名。
建議:用前兩個
# 讀取數據庫 from sqlalchemy import create_engine conn = create_engine('mysql+pymysql://root:root@127.0.0.1/test?charset=utf8', encoding='utf-8', echo=True) # data1 = pd.read_sql_query('select * from data', con=conn) # print(data1.head()) data2 = pd.read_sql_table('data', con=conn) print(data2.tail()) print(data2['X'][1])
數據庫連接字符串各參數說明
'mysql+pymysql://root:root@127.0.0.1/test?charset=utf8'
連接器://用戶名:密碼@數據庫所在IP/訪問的數據庫名稱?字符集
3數據寫出
3.1將數據寫出為csv
DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, mode='w', encoding=None, compression=None, quoting=None, quotechar='"', line_terminator='\n', chunksize=None, tupleize_cols=False, date_format=None, doublequote=True, escapechar=None, decimal='.')
- path_or_buf:數據存儲路徑,含文件全名例如'./data.csv'
- sep:表示數據存儲時使用的分隔符
- header:是否導出列名,True導出,False不導出
- index: 是否導出索引,True導出,False不導出
- mode:數據導出模式,'w'為寫
- encoding:數據導出的編碼
import pandas as pd data.to_csv('data.csv',index = False)
3.2將數據寫出為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)
- excel_writer:數據存儲路徑,含文件全名例如'./data.xlsx'
- sheet_name:表示數據存儲的工作簿名稱
- header:是否導出列名,True導出,False不導出
- index: 是否導出索引,True導出,False不導出
- encoding:數據導出的編碼
data.to_excel('data.xlsx',index=False)
3.3將數據寫入數據庫
DataFrame.to_sql(name, con, flavor=None, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None)
- name:數據存儲表名
- con:表示數據連接
- if_exists:判斷是否已經存在該表,'fail'表示存在就報錯;'replace'表示存在就覆蓋;'append'表示在尾部追加
- index: 是否導出索引,True導出,False不導出
from sqlalchemy import create_engine conn =create_engine('mysql+pymysql://root:root@127.0.0.1/data?charset=utf8', encoding='utf-8', echo=True) data.to_sql('data',con = conn)
4數據處理
4.1數據查看
# 查看前5行,5為數目,不是索引,默認為5 data.head() # 查看最后6行,6為數目,不是索引,默認為5 data.tail(6) # 查看數據的形狀 data.shape # 查看數據的列數,0為行1位列 data.shape[1] # 查看所有的列名 data.columns # 查看索引 data.index # 查看每一列數據的類型 data.dtypes # 查看數據的維度 data.ndim
## 查看數據基本情況 data.describe() ''' count:非空值的數目 mean:數值型數據的均值 std:數值型數據的標准差 min:數值型數據的最小值 25%:數值型數據的下四分位數 50%:數值型數據的中位數 75%:數值型數據的上四分位數 max:數值型數據的最大值 '''
4.2數據索引
# 取出單獨某一列 X = data['X'] # 取出多列 XY = data[['X','Y']] # 取出某列的某一行 data['X'][1] # 取出某列的某幾行 data['X'][:10] # 取出某幾列的某幾行 data[['X','Y']][:10]
# loc方法索引 ''' DataFrame.loc[行名,列名] ''' # 取出某幾列的某一行 data.loc[1,['X','月份']] # 取出某幾列的某幾行(連續) data.loc[1:5,['X','月份']] # 取出某幾列的某幾行(連續) data.loc[[1,3,5],['X','月份']] # 取出 x ,FFMC ,DC的0-20行所有索引名稱為偶數的數據 data.loc[range(0,21,2),['X','FFMC','DC']]
# iloc方法索引 ''' DataFrame.iloc[行位置,列位置] ''' # 取出某幾列的某一行 data.iloc[1,[1,4]] # 取出列位置為偶數,行位置為0-20的偶數的數據 data.iloc[0:21:2,0:data.shape[1]:2]
# ix方法索引 ''' DataFrame.ix[行位置/行名,列位置/列名] ''' ## 取出某幾列的某一行 data.ix[1:4,[1,4]] data.ix[1:4,1:4]
loc,iloc,ix的區別
- loc使用名稱索引,閉區間
- iloc使用位置索引,前閉后開區間
- ix使用名稱或位置索引,且優先識別名稱,其區間根據名稱/位置來改變
綜合上述所言,不建議使用ix,容易發生混淆的情況,並且運行效率低於loc和iloc,pandas考慮在后期會移除這一索引方法
4.3數據修改
# 修改列名 list1 = list(data.columns) list1[0] = '第一列' data.columns = list1 data['新增列'] = True data.loc['新增一行',:] = True data.drop('新增列',axis=1,inplace=True) data.drop('新增一行',axis=0,inplace=True)

import pandas as pd data = pd.read_excel('./data/test.xls') # 時間類型數據轉換 data['發生時間'] = pd.to_datetime(data['發生時間'],format='%Y%m%d%H%M%S') # 提取day data.loc[1,'發生時間'].day # 提取日期信息新建一列 data['日期'] = [i.day for i in data['發生時間']] year_data = [i.is_leap_year for i in data['發生時間']]
4.4分組聚合
4.4.1分組

# 分組 group1 = data.groupby('性別') group2 = data.groupby(['入職時間','性別']) # 查看有多少組 group1.size()
筆記:
用groupby方法分組后的結果並不能直接查看,而是被存在內存中,輸出的是內存地址。實際上分組后的數據對 象GroupBy類似Series與DataFrame,是pandas提供的一種對象。
4.4.2Groupby對象常見方法

4.4.3Grouped對象的agg方法
Grouped.agg(函數或包含了字段名和函數的字典)
# 第一種情況 group[['年齡','工資']].agg(min) # 對不同的列進行不同的聚合操作 group.agg({'年齡':max,'工資':sum}) # 上述過程中使用的函數均為系統math庫所帶的函數,若需要使用pandas的函數則需要做如下操作 group.agg({'年齡':lambda x:x.max(),'工資':lambda x:x.sum()})
4.4.4Grouped對象的apply聚合方法
Grouped.apply(函數操作)
只能對所有列執行同一種操作
group.apply(lambda x:x.max())
4.4.5Grouped對象的transform方法
grouped.transform(函數操作)
transform操作時的對象不再是每一組,而是每一個元素
# 每一空添加字符 group['年齡'].transform(lambda x: x.astype(str)+'歲').head() # 組內標准化 group1['工資'].transform(lambda x:(x.mean()-x.min())/(x.max()-x.min())).head()
