文章目錄
-
- 1、Series 有序(index)序列
-
-
- 1)建立Series
- 2)序列索引查找
-
- 2、Dataframe
-
-
- 1)建立dataftame (ndarray、dict、series)
- 2)建立符合索引的dataframe
- 3)資料資訊概覽
-
- 3、資料的讀取與儲存
-
-
- 1)讀寫excel檔案
- 2)讀寫csv檔案
- 3)讀寫HDF5檔案
- 4)讀寫SQL檔案
-
- 4、DataFrame的部分資料擷取
-
-
- a)按順序比對df.iloc[row_index, col_index]
- 2)按名字索引比對 df.loc[row_index, col_index]
- 3)按布爾值比對df[condition]
-
- 5、資料內建之concat、merge、insert
-
-
- 1)給dataframe增加一行
- 2)merge
-
- 6、資料清洗
-
-
- 1)處理重複值
- 2)處理缺失值
- 3)filter過濾篩選某個列變量
- 4)根據某種條件過濾資料
-
- 7、資料轉換
-
-
- 1)map的用法
- 2)apply的用法
- 3 transform
- 4)applymap針對每一個元素進行映射
- 4)打亂資料 np.random.permutation(length),也可以用random.shuffle()
-
- 8、資料形狀轉變
1、Series 有序(index)序列
pandas庫的很多功能或者方法是根據numpy來實作的,是以他們之間是由共通之處的,比如運算規則、資料結構。
pandas使用最多的兩的資料類型:
- Series 序列,包含索引(index)和資料值(values)
- DataFrame,資料框,結構類似于excel的表格,有列名(變量名),有索引index
import numpy as np
import pandas as pd
1)建立Series
s = pd.Series(
data=np.arange(5), # 序列值
index=list('abcde'), # 序列索引
dtype=np.int16, # 元素類型
name='序列名字', # 序列名字
copy=False,
fastpath=False )
s

2)序列索引查找
- 根據預設索引查找,預設的索引值是從0下标開始,length-1為結尾下标,查找規則和清單(list)切片一樣,查找範圍左閉右開
print(s[:2])
print(s[0])
- 根據指定索引查找,例如案例的索引是abcde,能了解吧,都告訴電腦了我要找确切的a索引所指向的值,是以查找區間是全閉合。
print(s['a':'b'])
print(s['c'])
2、Dataframe
俗稱資料框,簡寫為df,和excel的格式類似,由于方法衆多,且底層架構資料結構(類numpy,措辭不精準),是以處理資料友善且高效。
1)建立dataftame (ndarray、dict、series)
建立dataftame有多種方式,本文隻列舉常用的幾種,如通過ndarray,字典和Series建立df。
- 通過ndarray建立資料框
metaData = np.random.randint(0,20,size = (4,3))
df1 = pd.DataFrame(data=metaData,
index=list('ABCD'), # index
columns=['Python','Math','Eng'], # column_name
dtype=np.float16 ) # 資料類型
df1
- 字典,每一個key是一個變量,它的value就是該列所有的值。
df2 = pd.DataFrame(data = {'Python':[66,99,128],
'Math':[88,65,137],
'Eng':[100,121,45]})
df2
- series建立,一個series就是一條資料,也就是一行,series的name是它的所有
df3 = pd.DataFrame([pd.Series([1,2,3], name='pe'),
pd.Series([11,12,13], name='math')])
df3
2)建立符合索引的dataframe
有時候我們需要複合索引,俗稱多層或多級索引,例如,18年為一級索引,一、二、三月為二級索引,對應的水果銷量,這裡需要用到pd.MultiIndex.from_product([一級,二級])函數,詳情看案例代碼
data = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[11, 12, 13],
[14, 15, 16],
[17, 18, 19]])
df4 = pd.DataFrame(data=data,
columns=['apple', 'banana', 'orange'],
index = pd.MultiIndex.from_product([[ '18年', '19年' ],[ '一月','二月', '三月' ]]))
df4
3)資料資訊概覽
通常拿到一份資料,我們先會大緻了解資料的一個基本情況,例如樣本數量、次元、變量名、索引值、資料類型等,由于這些比較簡單易于了解,這裡不過多解釋了。直接看代碼和輸出結果就行,你可以的。
df4.shape # df的形狀
df4.ndim # 資料次元
df4.size # 資料元素大小=shape的内積
df4.columns # 列索引
df4.values # 值,傳回的是NumPy數組
df4.dtypes # 資料類型
display(df4.describe()) # 總體的統計summary()
df4.index # 行索引
df4.info() # 詳細資訊
3、資料的讀取與儲存
那麼問題來了,前面介紹了它的基本屬性,有了資料之後我們怎麼把資料加載到python環境下,利用強大的庫來做資料處理和資料分析呢?下面是pandas庫花式加載各種類型檔案,po碼
1)讀寫excel檔案
# 寫
df2.to_excel('./df2.xls', encoding='utf-8')
# 讀
pd.read_excel('./df2.xls')
2)讀寫csv檔案
- 寫入檔案,pd.to_csv()函數
df2.to_csv('./df2.csv',
sep=',', # 分隔符
index=False, # 不儲存行索引
header=True) # 把第一行當成變量名
print('儲存成功')
- 讀取檔案,pd.read_csv()函數
df_csv = pd.read_csv('./df2.csv')
df_csv
一般情況,大多數是将檔案儲存為csv格式,一是讀寫速度快一些,而是csv格式更加穩定,至于為什麼我也不懂。
3)讀寫HDF5檔案
hdf5 内部可以儲存多種類型資料,個人解讀類似excel一樣,表1,表2。比如深度學習中儲存模型就是h5檔案。
結構是group, dataset
df2.to_hdf('./df2.h5',key = 'score')
print('後h5檔案儲存成功!')
pd.read_hdf('./df2.h5',key = 'score')
4)讀寫SQL檔案
這裡隻簡單展示如何連接配接sql檔案,把sql檔案轉成dataframe在python中操作,處理資料
- 讀取sql檔案,利用pd.read_sql()函數,但是必須先連接配接上sql伺服器
from sqlalchemy import create_engine
engine = create_engine(
"mysql+pymysql://使用者名:密碼@localhost/資料庫?charset=utf8",
max_overflow=0, # 超過連接配接池大小外最多建立的連接配接數
pool_size=5, # 連接配接池大小
pool_timeout=30, # 連接配接池中沒有線程最多等待時間,否則報錯
pool_recycle=-1, # 多久之後對連接配接池中的連接配接進行回收(重置)-1不回收
)
sql_query = 'select * from a limit 2' # sql語句
res = pd.read_sql(sql_query, engine)
res
- 将檔案寫入sql資料庫
df.to_sql('table_name',
engine,
if_exists='append',
index=False,
chunksize=1000)
print("資料寫入成功!")
- 将DataFrame的資料儲存到資料庫表中,如果庫裡沒有該表名,則會自動建立該表
- if_exits: 三個模式:fail,若表存在,則不輸出;replace:若表存在,覆寫原來表裡的資料;append:若表存在,将資料寫到原表的後面。預設為fail
- index:是否将df的index單獨寫到一列中
- chunksize:設定一次入庫的大小
4、DataFrame的部分資料擷取
a)按順序比對df.iloc[row_index, col_index]
python中對于df的行和列,有預設行列索引,都從0開始,index=0,1,2…,取數的規則是根據索引index來取數
df2.iloc[1,2]
df2.iloc[:1, 2] # 類似切片,左閉右開
df[['Python', 'En']] # 選取多列
2)按名字索引比對 df.loc[row_index, col_index]
df2.loc[1, 'python']
df2.loc[1:3, ['python', 'math']] # 按照索引比對規則,全部比對上,因為你告訴了它詳細的位址
3)按布爾值比對df[condition]
傳回布爾值為True的該條資料
cond = df.Python > 80
# 将Python大于80分的成績擷取
df[cond]
cond = df.mean(axis = 1) > 75
# 平均分大于75,優秀,篩選出來
df[cond]
cond = (df.Python > 70) & (df.Math > 70)
df[cond]
5、資料內建之concat、merge、insert
準備資料:先建立了三位學生關于各科成績的一個表格,如下圖
d1 = pd.DataFrame(data = np.random.randint(0,20,3),
columns=['Python'],
index=['alex','jack','lisa'],
dtype=np.float16)
d2 = pd.DataFrame(data = np.random.randint(0,20,3),
columns=['Math'],
index=['alex','jack','lisa'],
dtype=np.float16)
d3 = pd.DataFrame(data = np.random.randint(0,20,3),
columns=['En'],
index=
['alex','jack','lisa'],
dtype=np.float16)
d2
1)給dataframe增加一行
- df.loc[row_index] = {key1:value1, key2:value2} 直接利用确切的行索引名字添加
d1.loc['ATM'] = {'Python':55}
- pd.concat([df1, df2]),可以在垂直拼接(axis=0),也可以左右拼接(axis=1),通過axis的值來控制,還有更多參數,連接配接方式有全連接配接、内連接配接(和sql差不多)。
pd.concat([df1,df2],
axis=0,
join='outer',
ignore_index: bool = False,
keys=None,
levels=None,
names=None)
pd.concat([d1,d2], axis=1) # 把同一個人的分數合并在一個表
- df.insert(loc, column, value)
d1.insert(0, 'English', d3 )
# 就地修改的, 插入一列
d1
2)merge
由于和sql中的連接配接類似,各個參數的作用大家可以參考原函數或者官方文檔,也可以百度,下面直接給案例吧(主要字碼累了~)
df1 = pd.DataFrame(data = {'name':['softpo','Brandon','Ella','Daniel','張三'],
'height':[175,180,169,177,168]}) # 身高
df2 = pd.DataFrame(data = {'name':['softpo','Brandon','Ella','Daniel','李四'],
'weight':[70,65,74,63,88]}) # 體重
df3 = pd.DataFrame(data = {'名字':['softpo','Brandon','Ella','Daniel','張三'],
'salary':np.random.randint(20,100,size = 5)}) # 薪水
- 内連接配接how=”inner“,隻顯示比對成功的值
- 左合并,坐标所有資料保留,不對應位置,填充了空資料
- 外合并,所有資料保留,不對應位置,填充了空資料
pd.merge(df1,df2,how = 'inner')
# 根據共同name進行合并,兩表合并,外鍵
6、資料清洗
1)處理重複值
df = pd.DataFrame(data = {'color':['red','blue','red','green','green','blue',None,np.NaN,'green'],
'price':[20,15,20,18,18,22,30,30,22]})
# 重複資料删除
df.drop_duplicates() # 有傳回值!非重複資料,索引7和索引6重複資料,None和NaN一回事
2)處理缺失值
- df.isna() 判斷是否缺失
- df.drop() 控制參數删除一列資料或者一行資料
- df.dropna() 預設一條資料隻要出現缺失值,直接删除該條資料
# 删除指定的列
df.drop(labels='color',axis = 1)
# 删除列,axis = 1
df.filter(items=['price'])
# 參數意思,保留資料price
df['size'] = 124
# 廣播
3)filter過濾篩選某個列變量
df.filter(like = 'i')
# 模糊比對,保留了帶有i這個字母的索引
df.filter(regex = 'e$')
# 正規表達式,正規表達式,限制e必須在最後
4)根據某種條件過濾資料
- 如異常值過濾
a = np.random.randint(0, 1000,size = 20)
# 異常值,大于800,小于 100算作異常,認為定義的。根據實際情況。
cond = (a <=800) & (a >=100)
a[cond]
7、資料轉換
transform和apply都可以作用在整個df上,map隻能作用在一列上,即map作用類Series。
- df.rename() 更改資料索引或者資料列名
- df.replace(old, new, inplace) 替換old資料值為new資料
df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
columns=['Python','Tensorflow','Keras'],
index = list('ABCDEFHIJK'))
df.rename(index = {'A':'X','K':'Y'}, # 行索引
columns={'Python':'人工智能'}, # 列索引修改
inplace=True) # 替換原資料
df.replace(5, 50,inplace=True) # 針對全局的5換成50
df.replace([2,7],1024,inplace=True)
準備一個資料,代碼如下:
boolean=[True,False]
gender=["男","女"]
color=["white","black","yellow"]
data=pd.DataFrame({
"height":np.random.randint(150,190,100),
"weight":np.random.randint(40,90,100),
"smoker":[boolean[x] for x in np.random.randint(0,2,100)],
"gender":[gender[x] for x in np.random.randint(0,2,100)],
"age":np.random.randint(15,90,100),
"color":[color[x] for x in np.random.randint(0,len(color),100) ]
})
資料如下:
1)map的用法
不論是利用字典還是函數進行映射,map方法都是把對應的資料逐個當作參數傳入到字典或函數中,主要作用與Series,得到映射後的值。
# 1、使用字典進行映射
data["gender"] = data["gender"].map({"男":1, "女":0})
#2、使用函數
def gender_map(x):
gender = 1 if x == "男" else 0
return gender
#注意這裡傳入的是函數名,不帶括号
data["gender"] = data["gender"].map(gender_map)
2)apply的用法
apply方法的作用原理和map方法類似,差別在于apply可以作用在series和dataframe上,而map隻能作用在series上,并且apply能夠傳入功能更為複雜的函數。
# apply既可以操作Series又可以操作DataFrame
df['人工智能'].apply(lambda x : x + 100)
df['level'].apply(lambda x:1 if x else 0)
df.apply(lambda x : x + 1000) # apply對 所有的資料進行映射
def convert(x):
return (x.median(),x.count(),x.min(),x.max(),x.std()) # 傳回中位數,傳回的是計數
df.apply(convert).round(1) # 預設操作列資料
df.apply(convert,axis = 1) # axis = 1,操作資料就是行資料
3 transform
df = pd.DataFrame(np.random.randint(0,10,size = (10,3)),
columns=['Python','Tensorflow','Keras'],
index = list('ABCDEFHIJK'))
# 可以針對一列資料,Series進行運算
df['Python'][:5].transform(lambda x : 1024 if x > 5 else -1024) # 這個功能和map,apply類似的
df['Tensorflow'].apply([np.sqrt, np.square, np.cumsum]) # 針對一列,進行不同的操作
df['Tensorflow'].transform([np.sqrt, np.square, np.cumsum]) # 針對一列,進行不同的操作
4)applymap針對每一個元素進行映射
def convert(x):
if x > 5:
return True
else:
return False
# 可以針對DataFrame進行運算
df.transform({'Python':np.cumsum,'Tensorflow':np.square,'Keras':convert}) # 對不同的列,執行不同的操作
df.apply({'Python':np.cumsum,'Tensorflow':np.square,'Keras':convert}) # 對不同的列,執行不同的操作
4)打亂資料 np.random.permutation(length),也可以用random.shuffle()
- np.random.permutation()的機制是随機打亂一個連續自然數的順序,然後根據随機的index取出資料。
index = np.random.permutation(10) # 傳回打亂順訊的索引
print(index)
# 重排,索引打亂
df.take(index)
# 從大量資料中随機抽取資料
df.iloc[:5,].take(np.random.randint(0,10,size = 2)) # 随機抽樣2個資料
-
類别型編碼編碼,有one-hot和啞變量編碼,二者本質差不多,隻是啞變量比獨熱編碼要少一個字變量。
one-hot,啞變量;
str類型資料,經過啞變量變換可以使用數字表示
pd.get_dummies(df2,prefix='',prefix_sep='')
# 1表示 True;0表示 False
8、資料形狀轉變
- df.T 行列互換
- df.transpose() 行列互換
df2 = pd.DataFrame(np.random.randint(0,10,size = (6,3)),
columns=['Python','Math','En'],
index = pd.MultiIndex.from_product([list('ABC'),['期中','期末']])) # 多層索引
df2
- df.unstack(level) 将行索引變成列索引,-1表示最後一層(最裡面一層)
- 将行索引變成列索引,-1表示最後一層(最裡面一層)
df.stack() 把列索引(列名字)放在行索引的位置,相當于減少列數,增加行數。