Pandas數(shù)據(jù)結(jié)構(gòu)Series:基本概念及創(chuàng)建
Series 是帶有標(biāo)簽的一維數(shù)組,可以保存任何數(shù)據(jù)類型(整數(shù),字符串,浮點(diǎn)數(shù),Python對(duì)象等),軸標(biāo)簽統(tǒng)稱為索引
# 導(dǎo)入numpy、pandas模塊
import numpy as np
import pandas as pd
# 查看數(shù)據(jù)、數(shù)據(jù)類型
s = pd.Series(np.random.rand(5))
print(s)
print(type(s))
# .index查看series索引,類型為rangeindex
# .values查看series值,類型是ndarray
print(s.index,type(s.index))
print(s.values,type(s.values))
核心:series相比于ndarray,是一個(gè)自帶索引index的數(shù)組 → 一維數(shù)組 + 對(duì)應(yīng)索引,所以當(dāng)只看series的值的時(shí)候,就是一個(gè)ndarray
series和ndarray較相似,索引切片功能差別不大
series和dict相比,series更像一個(gè)有順序的字典(dict本身不存在順序),其索引原理與字典相似(一個(gè)用key,一個(gè)用index)
Series 創(chuàng)建方法的三種方法
Series 創(chuàng)建方法一:由字典創(chuàng)建,字典的key就是index,values
就是values
dic = {'a':1 ,'b':2 , 'c':3, '4':4, '5':5}
s = pd.Series(dic)
print(s)
# 注意:key肯定是字符串,假如values類型不止一個(gè)會(huì)怎么樣? → dic = {'a':1 ,'b':'hello' , 'c':3, '4':4, '5':5}
Series 創(chuàng)建方法二:由數(shù)組創(chuàng)建(一維數(shù)組)
# 默認(rèn)index是從0開(kāi)始,步長(zhǎng)為1的數(shù)字
arr = np.random.randn(5)
s = pd.Series(arr)
print(arr)
print(s)
# index參數(shù):設(shè)置index,長(zhǎng)度保持一致
# dtype參數(shù):設(shè)置數(shù)值類型
s = pd.Series(arr, index = ['a','b','c','d','e'],dtype = np.object)
print(s)
Series 創(chuàng)建方法三:由標(biāo)量創(chuàng)建
# 如果data是標(biāo)量值,則必須提供索引。該值會(huì)重復(fù),來(lái)匹配索引的長(zhǎng)度
s = pd.Series(10, index = range(4))
print(s)
Series 名稱屬性:name
# name為Series的一個(gè)參數(shù),創(chuàng)建一個(gè)數(shù)組的 名稱
# .name方法:輸出數(shù)組的名稱,輸出格式為str,如果沒(méi)用定義輸出名稱,輸出為None
s1 = pd.Series(np.random.randn(5))
print(s1)
print('-----')
s2 = pd.Series(np.random.randn(5),name = 'test')
print(s2)
print(s1.name, s2.name,type(s2.name))
# .rename()重命名一個(gè)數(shù)組的名稱,并且新指向一個(gè)數(shù)組,原數(shù)組不變
s3 = s2.rename('hehehe')
print(s3)
print(s3.name, s2.name)
Pandas數(shù)據(jù)結(jié)構(gòu)Series:索引
位置下標(biāo) / 標(biāo)簽索引 / 切片索引 / 布爾型索引
位置下標(biāo),類似序列
#print(s[-1])
# 位置下標(biāo)從0開(kāi)始
# 輸出結(jié)果為numpy.float格式,
# 可以通過(guò)float()函數(shù)轉(zhuǎn)換為python float格式
# numpy.float與float占用字節(jié)不同
# s[-1]結(jié)果如何?
s = pd.Series(np.random.rand(5))
print(s)
print(s[0],type(s[0]),s[0].dtype)
print(float(s[0]),type(float(s[0])))
標(biāo)簽索引
# 方法類似下標(biāo)索引,用[]表示,內(nèi)寫(xiě)上index,注意index是字符串
s = pd.Series(np.random.rand(5), index = ['a','b','c','d','e'])
print(s)
print(s['a'],type(s['a']),s['a'].dtype)
# 如果需要選擇多個(gè)標(biāo)簽的值,用[[]]來(lái)表示(相當(dāng)于[]中包含一個(gè)列表)
# 多標(biāo)簽索引結(jié)果是新的數(shù)組
sci = s[['a','b','e']]
print(sci,type(sci))
切片索引
# 注意:用index做切片是末端包含
s1 = pd.Series(np.random.rand(5))
s2 = pd.Series(np.random.rand(5), index = ['a','b','c','d','e'])
print(s1[1:4],s1[4])
print(s2['a':'c'],s2['c'])
print(s2[0:3],s2[3])
print('-----')
# 下標(biāo)索引做切片,和list寫(xiě)法一樣# 下標(biāo)索引做切片,和list寫(xiě)法一樣
print(s2[:-1])
print(s2[::2])
布爾型索引
# 數(shù)組做判斷之后,返回的是一個(gè)由布爾值組成的新的數(shù)組
# .isnull() / .notnull() 判斷是否為空值 (None代表空值,NaN代表有問(wèn)題的數(shù)值,兩個(gè)都會(huì)識(shí)別為空值)
s = pd.Series(np.random.rand(3)*100)
s[4] = None # 添加一個(gè)空值
print(s)
bs1 = s > 50
bs2 = s.isnull()
bs3 = s.notnull()
print(bs1, type(bs1), bs1.dtype)
print(bs2, type(bs2), bs2.dtype)
print(bs3, type(bs3), bs3.dtype)
print('-----')
# 布爾型索引方法:用[判斷條件]表示,其中判斷條件可以是 一個(gè)語(yǔ)句,或者是 一個(gè)布爾型數(shù)組!
print(s[s > 50])
print(s[bs3])
Pandas數(shù)據(jù)結(jié)構(gòu)Series:基本技巧
數(shù)據(jù)查看 / 重新索引 / 對(duì)齊 / 添加、修改、刪除值
數(shù)據(jù)查看
# .head()查看頭部數(shù)據(jù)
# .tail()查看尾部數(shù)據(jù)
# 默認(rèn)查看5條
s = pd.Series(np.random.rand(50))
print(s.head(10))
print(s.tail())
重新索引reindex
# .reindex將會(huì)根據(jù)索引重新排序,如果當(dāng)前索引不存在,則引入缺失值
# .reindex()中也是寫(xiě)列表
# 這里'd'索引不存在,所以值為NaN
s = pd.Series(np.random.rand(3), index = ['a','b','c'])
print(s)
s1 = s.reindex(['c','b','a','d'])
print(s1)
# fill_value參數(shù):填充缺失值的值
s2 = s.reindex(['c','b','a','d'], fill_value = 0)
print(s2)
Series對(duì)齊
# Series 和 ndarray 之間的主要區(qū)別是,Series 上的操作會(huì)根據(jù)標(biāo)簽自動(dòng)對(duì)齊
# index順序不會(huì)影響數(shù)值計(jì)算,以標(biāo)簽來(lái)計(jì)算
# 空值和任何值計(jì)算結(jié)果扔為空值
s1 = pd.Series(np.random.rand(3), index = ['Jack','Marry','Tom'])
s2 = pd.Series(np.random.rand(3), index = ['Wang','Jack','Marry'])
print(s1)
print(s2)
print(s1+s2)
刪除:.drop
# drop 刪除元素之后返回副本(inplace=False)
s = pd.Series(np.random.rand(5), index = list('ngjur'))
print(s)
s1 = s.drop('n')
s2 = s.drop(['g','j'])
print(s1)
print(s2)
print(s)
添加
# 直接通過(guò)下標(biāo)索引/標(biāo)簽index添加值
s1 = pd.Series(np.random.rand(5))
s2 = pd.Series(np.random.rand(5), index = list('ngjur'))
print(s1)
print(s2)
s1[5] = 100
s2['a'] = 100
print(s1)
print(s2)
# 通過(guò).append方法,直接添加一個(gè)數(shù)組
# .append方法生成一個(gè)新的數(shù)組,不改變之前的數(shù)組
s3 = s1.append(s2)
print(s3)
print(s1)
修改
# 通過(guò)索引直接修改,類似序列
s = pd.Series(np.random.rand(3), index = ['a','b','c'])
print(s)
s['a'] = 100
s[['b','c']] = 200
print(s)
Pandas數(shù)據(jù)結(jié)構(gòu)Dataframe:基本概念及創(chuàng)建
"二維數(shù)組"Dataframe:是一個(gè)表格型的數(shù)據(jù)結(jié)構(gòu),包含一組有序的列,其列的值類型可以是數(shù)值、字符串、布爾值等。
Dataframe中的數(shù)據(jù)以一個(gè)或多個(gè)二維塊存放,不是列表、字典或一維數(shù)組結(jié)構(gòu)。
Dataframe 數(shù)據(jù)結(jié)構(gòu)
Dataframe是一個(gè)表格型的數(shù)據(jù)結(jié)構(gòu),“帶有標(biāo)簽的二維數(shù)組”。
Dataframe帶有index(行標(biāo)簽)和columns(列標(biāo)簽)
# 查看數(shù)據(jù),數(shù)據(jù)類型為dataframe
# .index查看行標(biāo)簽
# .columns查看列標(biāo)簽
# .values查看值,數(shù)據(jù)類型為ndarray
data = {'name':['Jack','Tom','Mary'],
'age':[18,19,20],
'gender':['m','m','w']}
frame = pd.DataFrame(data)
print(frame)
print(type(frame))
print(frame.index,'\n該數(shù)據(jù)類型為:',type(frame.index))
print(frame.columns,'\n該數(shù)據(jù)類型為:',type(frame.columns))
print(frame.values,'\n該數(shù)據(jù)類型為:',type(frame.values))
Dataframe 五種創(chuàng)建方法
Dataframe 創(chuàng)建方法一:由數(shù)組/list組成的字典
創(chuàng)建方法:pandas.Dataframe()
# 由數(shù)組/list組成的字典 創(chuàng)建Dataframe,columns為字典key,index為默認(rèn)數(shù)字標(biāo)簽
# 字典的值的長(zhǎng)度必須保持一致!
data1 = {'a':[1,2,3],
'b':[3,4,5],
'c':[5,6,7]}
data2 = {'one':np.random.rand(3),
'two':np.random.rand(3)} # 這里如果嘗試 'two':np.random.rand(4) 會(huì)怎么樣?
print(data1)
print(data2)
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
print(df1)
print(df2)
# columns參數(shù):可以重新指定列的順序,格式為list,如果現(xiàn)有數(shù)據(jù)中沒(méi)有該列(比如'd'),則產(chǎn)生NaN值
# 如果columns重新指定時(shí)候,列的數(shù)量可以少于原數(shù)據(jù)
df1 = pd.DataFrame(data1, columns = ['b','c','a','d'])
print(df1)
df1 = pd.DataFrame(data1, columns = ['b','c'])
print(df1)
# index參數(shù):重新定義index,格式為list,長(zhǎng)度必須保持一致
df2 = pd.DataFrame(data2, index = ['f1','f2','f3']) # 這里如果嘗試 index = ['f1','f2','f3','f4'] 會(huì)怎么樣?
print(df2)
Dataframe 創(chuàng)建方法二:由Series組成的字典
# 由Seris組成的字典 創(chuàng)建Dataframe,columns為字典key,index為Series的標(biāo)簽(如果Series沒(méi)有指定標(biāo)簽,則是默認(rèn)數(shù)字標(biāo)簽)
# Series可以長(zhǎng)度不一樣,生成的Dataframe會(huì)出現(xiàn)NaN值
data1 = {'one':pd.Series(np.random.rand(2)),
'two':pd.Series(np.random.rand(3))} # 沒(méi)有設(shè)置index的Series
data2 = {'one':pd.Series(np.random.rand(2), index = ['a','b']),
'two':pd.Series(np.random.rand(3),index = ['a','b','c'])} # 設(shè)置了index的Series
print(data1)
print(data2)
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
print(df1)
print(df2)
Dataframe 創(chuàng)建方法三:通過(guò)二維數(shù)組直接創(chuàng)建
# 通過(guò)二維數(shù)組直接創(chuàng)建Dataframe,得到一樣形狀的結(jié)果數(shù)據(jù),如果不指定index和columns,兩者均返回默認(rèn)數(shù)字格式
# index和colunms指定長(zhǎng)度與原數(shù)組保持一致
ar = np.random.rand(9).reshape(3,3)
print(ar)
df1 = pd.DataFrame(ar)
df2 = pd.DataFrame(ar, index = ['a', 'b', 'c'], columns = ['one','two','three']) # 可以嘗試一下index或columns長(zhǎng)度不等于已有數(shù)組的情況
print(df1)
print(df2)
Dataframe 創(chuàng)建方法四:由字典組成的列表
# 由字典組成的列表創(chuàng)建Dataframe,columns為字典的key,index不做指定則為默認(rèn)數(shù)組標(biāo)簽
# colunms和index參數(shù)分別重新指定相應(yīng)列及行標(biāo)簽
data = [{'one': 1, 'two': 2}, {'one': 5, 'two': 10, 'three': 20}]
print(data)
df1 = pd.DataFrame(data)
df2 = pd.DataFrame(data, index = ['a','b'])
df3 = pd.DataFrame(data, columns = ['one','two'])
print(df1)
print(df2)
print(df3)
Dataframe 創(chuàng)建方法五:由字典組成的字典
# 由字典組成的字典創(chuàng)建Dataframe,columns為字典的key,index為子字典的key
data = {'Jack':{'math':90,'english':89,'art':78},
'Marry':{'math':82,'english':95,'art':92},
'Tom':{'math':78,'english':67}}
df1 = pd.DataFrame(data)
print(df1)
# columns參數(shù)可以增加和減少現(xiàn)有列,如出現(xiàn)新的列,值為NaN
# index在這里和之前不同,并不能改變?cè)衖ndex,如果指向新的標(biāo)簽,值為NaN (非常重要?。?df2 = pd.DataFrame(data, columns = ['Jack','Tom','Bob'])
df3 = pd.DataFrame(data, index = ['a','b','c'])
print(df2)
print(df3)
Pandas數(shù)據(jù)結(jié)構(gòu)Dataframe:索引
Dataframe既有行索引也有列索引,可以被看做由Series組成的字典(共用一個(gè)索引)
選擇列 / 選擇行 / 切片 / 布爾判斷
選擇行與列
df = pd.DataFrame(np.random.rand(12).reshape(3,4)*100,
index = ['one','two','three'],
columns = ['a','b','c','d'])
print(df)
# 按照列名選擇列,只選擇一列輸出Series,選擇多列輸出Dataframe
data1 = df['a']
data2 = df[['a','c']]
print(data1,type(data1))
print(data2,type(data2))
# 按照index選擇行,只選擇一行輸出Series,選擇多行輸出Dataframe
data3 = df.loc['one']
data4 = df.loc[['one','two']]
print(data2,type(data3))
print(data3,type(data4))
df[] - 選擇列
一般用于選擇列,也可以選擇行
df = pd.DataFrame(np.random.rand(12).reshape(3,4)*100,
index = ['one','two','three'],
columns = ['a','b','c','d'])
print(df)
# df[]默認(rèn)選擇列,[]中寫(xiě)列名(所以一般數(shù)據(jù)colunms都會(huì)單獨(dú)制定,不會(huì)用默認(rèn)數(shù)字列名,以免和index沖突)
# 單選列為Series,print結(jié)果為Series格式
# 多選列為Dataframe,print結(jié)果為Dataframe格式
data1 = df['a']
data2 = df[['b','c']] # 嘗試輸入 data2 = df[['b','c','e']]
print(data1)
print(data2)
# df[]中為數(shù)字時(shí),默認(rèn)選擇行,且只能進(jìn)行切片的選擇,不能單獨(dú)選擇(df[0])
# 輸出結(jié)果為Dataframe,即便只選擇一行
# df[]不能通過(guò)索引標(biāo)簽名來(lái)選擇行(df['one'])
data3 = df[:1]
#data3 = df[0]
#data3 = df['one']
print(data3,type(data3))
核心筆記:df[col]一般用于選擇列,[]中寫(xiě)列名
df.loc[] - 按index選擇行
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
df2 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print(df1)
print(df2)
# 單個(gè)標(biāo)簽索引,返回Series
data1 = df1.loc['one']
data2 = df2.loc[1]
print(data1)
print(data2)
# 多個(gè)標(biāo)簽索引,如果標(biāo)簽不存在,則返回NaN
# 順序可變
data3 = df1.loc[['two','three','five']]
data4 = df2.loc[[3,2,1]]
print(data3)
print(data4)
print('多標(biāo)簽索引\n-----')
# 可以做切片對(duì)象
# 末端包含
data5 = df1.loc['one':'three']
data6 = df2.loc[1:3]
print(data5)
print(data6)
print('切片索引')
核心筆記:df.loc[label]主要針對(duì)index選擇行,同時(shí)支持指定index,及默認(rèn)數(shù)字index
df.iloc[] - 按照整數(shù)位置(從軸的0到length-1)選擇行
類似list的索引,其順序就是dataframe的整數(shù)位置,從0開(kāi)始計(jì)
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print(df)
# 單位置索引
# 和loc索引不同,不能索引超出數(shù)據(jù)行數(shù)的整數(shù)位置
print(df.iloc[0])
print(df.iloc[-1])
#print(df.iloc[4])
print('單位置索引')
# 多位置索引
# 順序可變
print(df.iloc[[0,2]])
print(df.iloc[[3,2,1]])
print('多位置索引')
# 切片索引
# 末端不包含
print(df.iloc[1:3])
print(df.iloc[::2])
print('切片索引')
布爾型索引
和Series原理相同
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print(df)
# 不做索引則會(huì)對(duì)數(shù)據(jù)每個(gè)值進(jìn)行判斷
# 索引結(jié)果保留 所有數(shù)據(jù):True返回原數(shù)據(jù),F(xiàn)alse返回值為NaN
b1 = df < 20
print(b1,type(b1))
print(df[b1]) # 也可以書(shū)寫(xiě)為 df[df < 20]
# 單列做判斷
# 索引結(jié)果保留 單列判斷為T(mén)rue的行數(shù)據(jù),包括其他列
b2 = df['a'] > 50
print(b2,type(b2))
print(df[b2]) # 也可以書(shū)寫(xiě)為 df[df['a'] > 50]
# 多列做判斷
# 索引結(jié)果保留 所有數(shù)據(jù):True返回原數(shù)據(jù),F(xiàn)alse返回值為NaN
b3 = df[['a','b']] > 50
print(b3,type(b3))
print(df[b3]) # 也可以書(shū)寫(xiě)為 df[df[['a','b']] > 50]
# 多行做判斷
# 索引結(jié)果保留 所有數(shù)據(jù):True返回原數(shù)據(jù),F(xiàn)alse返回值為NaN
b4 = df.loc[['one','three']] < 50
print(b4,type(b4))
print(df[b4]) # 也可以書(shū)寫(xiě)為 df[df.loc[['one','three']] < 50]
多重索引:比如同時(shí)索引行和列
先選擇列再選擇行 —— 相當(dāng)于對(duì)于一個(gè)數(shù)據(jù),先篩選字段,再選擇數(shù)據(jù)量
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print(df)
print(df['a'].loc[['one','three']]) # 選擇a列的one,three行
print(df[['b','c','d']].iloc[::2]) # 選擇b,c,d列的one,three行
print(df[df['a'] < 50].iloc[:2]) # 選擇滿足判斷索引的前兩行數(shù)據(jù)
Pandas數(shù)據(jù)結(jié)構(gòu)Dataframe:基本技巧
數(shù)據(jù)查看、轉(zhuǎn)置 / 添加、修改、刪除值 / 對(duì)齊 / 排序
數(shù)據(jù)查看、轉(zhuǎn)置
# .head()查看頭部數(shù)據(jù)
# .tail()查看尾部數(shù)據(jù)
# 默認(rèn)查看5條
df = pd.DataFrame(np.random.rand(16).reshape(8,2)*100,
columns = ['a','b'])
print(df.head(2))
print(df.tail())
# .T 轉(zhuǎn)置
print(df.T)
添加與修改
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print(df)
# 新增列/行并賦值
df['e'] = 10
df.loc[4] = 20
print(df)
# 索引后直接修改值
df['e'] = 20
df[['a','c']] = 100
print(df)
刪除 del / drop()
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print(df)
# del語(yǔ)句 - 刪除列
del df['a']
print(df)
# drop()刪除行,inplace=False → 刪除后生成新的數(shù)據(jù),不改變?cè)瓟?shù)據(jù)
print(df.drop(0))
print(df.drop([1,2]))
print(df)
# drop()刪除列,需要加上axis = 1,inplace=False → 刪除后生成新的數(shù)據(jù),不改變?cè)瓟?shù)據(jù)
print(df.drop(['d'], axis = 1))
print(df)
對(duì)齊
# DataFrame對(duì)象之間的數(shù)據(jù)自動(dòng)按照列和索引(行標(biāo)簽)對(duì)齊
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D'])
df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C'])
print(df1 + df2)
排序1 - 按值排序 .sort_values
同樣適用于Series
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print(df1)
# ascending參數(shù):設(shè)置升序降序,默認(rèn)升序
# 單列排序
print(df1.sort_values(['a'], ascending = True)) # 升序
print(df1.sort_values(['a'], ascending = False)) # 降序
# 多列排序,按列順序排序
df2 = pd.DataFrame({'a':[1,1,1,1,2,2,2,2],
'b':list(range(8)),
'c':list(range(8,0,-1))})
print(df2)
print(df2.sort_values(['a','c']))
排序2 - 索引排序 .sort_index
# 按照index排序
# 默認(rèn) ascending=True, inplace=False
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = [5,4,3,2],
columns = ['a','b','c','d'])
df2 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['h','s','x','g'],
columns = ['a','b','c','d'])
print(df1)
print(df1.sort_index())
print(df2)
print(df2.sort_index())