list取数据_Day.5利用Pandas做数据处理(二)
生活随笔
收集整理的這篇文章主要介紹了
list取数据_Day.5利用Pandas做数据处理(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據合并
使用Join()合并,合并的方式是根據行和行進行合并。
# 使用join合并,著重關注的是 行的合并import pandas as pd df1=pd.DataFrame({'Red':[1,3,5],'Green':[5,0,3]},index=list('abc'))df2=pd.DataFrame({'Blue':[1,9,8],'Yellow':[6,6,7]},index=list('cde'))print(df1)print(df2)''' ? Red Greena ? 1 ? ? 5b ? 3 ? ? 0c ? 5 ? ? 3 ? Blue Yellowc ? ? 1 ? ? ? 6d ? ? 9 ? ? ? 6e ? ? 8 ? ? ? 7'''# 簡單合并(默認是left左連接,以左側df1為基礎,連接右側中index相同的行)df3=df1.join(df2,how='left')print(df3)''' ? Red Green Blue Yellowa ? 1 ? ? 5 ? NaN ? ? NaNb ? 3 ? ? 0 ? NaN ? ? NaNc ? 5 ? ? 3 ? 1.0 ? ? 6.0'''# 右連接:以左側df2為基礎,連接左側df1中index相同的行df4 = df1.join(df2,how='right')print(df4)''' ? Red Green Blue Yellowc 5.0 ? 3.0 ? ? 1 ? ? ? 6d NaN ? NaN ? ? 9 ? ? ? 6e NaN ? NaN ? ? 8 ? ? ? 7'''# 外連接(左右兩側的index全連接,取并集)df5 = df1.join(df2,how='outer')print(df5)''' ? Red Green Blue Yellowa 1.0 ? 5.0 ? NaN ? ? NaNb 3.0 ? 0.0 ? NaN ? ? NaNc 5.0 ? 3.0 ? 1.0 ? ? 6.0d NaN ? NaN ? 9.0 ? ? 6.0e NaN ? NaN ? 8.0 ? ? 7.0'''# 合并多個DataFrame對象df6 = pd.DataFrame({'Brown':[3,4,5],'White':[1,1,2]},index=list('aed'))print(df6)df7 = df2.join([df1,df6])print(df7)''' ? Brown Whitea ? ? 3 ? ? 1e ? ? 4 ? ? 1d ? ? 5 ? ? 2 ? Blue Yellow Red Green Brown Whitec ? ? 1 ? ? ? 6 5.0 ? 3.0 ? NaN ? NaNd ? ? 9 ? ? ? 6 NaN ? NaN ? 5.0 ? 2.0e ? ? 8 ? ? ? 7 NaN ? NaN ? 4.0 ? 1.0'''merge()函數是列和列合并。
# 使用merge,著重關注的是列的合并df1=pd.DataFrame({'名字':list('ABCDE'),'性別'['男','女','男','男','女'],'職稱':['副教授','講師','助教','教授','助教']},index=range(1001,1006))print(df1)''' ? ? 名字 性別 ? 職稱1001 A 男 副教授1002 B 女 ? 講師1003 C 男 ? 助教1004 D 男 ? 教授1005 E 女 ? 助教'''df2=pd.DataFrame({'名字':list('ABDAX'),'課程':['C++','計算機導論','匯編','數據結構','馬克思原理'],'職稱':['副教授','講師','教授','副教授','講師']},index=[1001,1002,1004,1001,3001])print(df2)''' ? ? 名字 ? ? 課程 ? 職稱1001 A ? C++ 副教授1002 B 計算機導論 ? 講師1004 D ? ? 匯編 ? 教授1001 A ? 數據結構 副教授3001 X 馬克思原理 ? 講師'''# merge默認根據左右對象中出現同名的列作為連接的鍵,且連接方式是how=’inner’內連接,內連接取兩者交集print(pd.merge(df1,df2))''' 名字 性別 ? 職稱 ? ? 課程0 A 男 副教授 ? C++1 A 男 副教授 ? 數據結構2 B 女 ? 講師 計算機導論3 D 男 ? 教授 ? ? 匯編'''# 指定列名合并,suffixes來設置重復列的名字print(pd.merge(df1,df2,on='名字',suffixes=['_1','_2']))''' 名字 性別 職稱_1 課程 ? ? 職稱_20 A 男 副教授 ? C++ ? ? 副教授1 A 男 副教授 ? 數據結構 副教授2 B 女 ? 講師 計算機導論 講師3 D 男 ? 教授 ? ? 匯編 ? 教授'''# 左連接,根據左側為準print(pd.merge(df1,df2,how='left'))'''名字 性別 ? 職稱 ? ? 課程0 A 男 副教授 ? C++1 A 男 副教授 ? 數據結構2 B 女 ? 講師 計算機導論3 C 男 ? 助教 ? NaN4 D 男 ? 教授 ? ? 匯編5 E 女 ? 助教 ? NaN'''# 右連接,根據右側為準print(pd.merge(df1,df2,how='right'))''' 名字 ? 性別 ? 職稱 ? ? 課程0 A ? 男 副教授 ? C++1 A ? 男 副教授 ? 數據結構2 B ? 女 ? 講師 計算機導論3 D ? 男 ? 教授 ? ? 匯編4 X NaN ? 講師 馬克思原理'''# 合并所有 取并集print(pd.merge(df1,df2,how='outer'))''' 名字 性別 ? 職稱 ? ? 課程0 A ? 男 副教授 ? C++1 A ? 男 副教授 ? 數據結構2 B ? 女 ? 講師 計算機導論3 C ? 男 ? 助教 ? NaN4 D ? 男 ? 教授 ? ? 匯編5 E ? 女 ? 助教 ? NaN6 X NaN ? 講師 馬克思原理'''# 根據多個鍵進行連接print(pd.merge(df1,df2,on=['職稱','名字']))''' 名字 性別 職稱 ? ? 課程0 A 男 副教授 ? C++1 A 男 副教授 ? 數據結構2 B 女 ? 講師 計算機導論3 D 男 ? 教授 ? ? 匯編'''多層索引
這里簡單介紹一下多層索引,多層級索引,將指標進行分層,索引具有層級結構,可以使得高維度的數據進行降維。
先來學習一下Series對象創建多層索引,并對索引對象查詢。
import numpy as npimport pandas as pdfrom pandas import Series,DataFrame# Series創建多層索引s = Series(np.random.randint(0,150,size=6),index=list('abcdef'))print(s) # 原索引s = Series(np.random.randint(0,150,size=6),index=[['a','a','b','b','c','c'],['期中','期末','期中','期末','期中','期末']]) # 創建多層索引print(s)# Series索引對象的獲取# 取一個第一級索引print(s['a'])# 取多個第一級索引print(s[['a','b']])# 根據索引獲取值print(s['a','期末'])# loc方法取值 根據標簽名取值print(s.loc['a'])print(s.loc[['a','b']])print(s.loc['a','期末'])# # iloc方法取值 根據位置取值 (iloc計算的是最內層索引,直接跳過層級,最內層開始取)print(s.iloc[1])print(s.iloc[1:4])# 注:列值中的數字是隨機數,這里不附上運行結果,可以先把復制過去,全部注釋,然后一行一行的運行接下來介紹DataFrame創建多層索引的三種方式,及其索引對象的查詢。
import numpy as npimport pandas as pdfrom pandas import Series,DataFrame# DataFrame創建多層索引# 方式一:index由兩個數組組成df1 = DataFrame(np.random.randint(0,150,size=(6,4)),columns = ['shon','jack','meili','dafeng'], ? ? ? ? ? ? ? ?index = [['python','python','math','math','En','En'],['期中','期末','期中','期末','期中','期末']])print(df1)# 方式二:特定結構class1=['python','python','math','math','En','En']class2=['期中','期末','期中','期末','期中','期末']m_index2=pd.MultiIndex.from_arrays([class1,class2])df2=DataFrame(np.random.randint(0,150,(6,4)),index=m_index2)print(df2)# 方式三:乘法方式 product意為乘法class1=['python','math','En']class2=['期中','期末']m_index2=pd.MultiIndex.from_product([class1,class2])df3=DataFrame(np.random.randint(0,150,(6,4)),index=m_index2)print(df3)# Series索引對象的獲取# 獲取列:print(df1['shon'])# 一級索引print(df1.loc['python'])# 多個一級索引print(df1.loc[['python','math']])# 取一行print(df1.loc['python','期末'])# 取一值print(df1.loc['python','期末'][0])# iloc是只取最內層的索引的print(df2.iloc[0])時間序列
時間序列是指將同一統計指標的數值按其發生的時間先后順序排列而成的數列。時間序列分析的主要目的是根據已有的歷史數據對未來進行預測。經濟數據中大多數以時間序列的形式給出。根據觀察時間的不同,時間序列中的時間可以是年份、季度、月份或其他任何時間形式,下面是如何創建時間序列。
import pandas as pdimport numpy as np# 1. 生成一段時間范圍'''data_range(start、end、periods)函數主要用于生成一個固定頻率的時間索引,使用時須指定三個參數中的兩個參數值,否則報錯。時間序列頻率: ? D 日歷日的每天 ? B 工作日的每天 ? H 每小時 ? T或min 每分鐘 ? S 每秒 ? L或ms 每毫秒 ? U 每微秒 ? M 日歷日的月底日期 ? BM 工作日的月底日期 ? MS 日歷日的月初日期 ? BMS 工作日的月初日期freq:日期偏移量,取值為string, 默認為'D', freq='1h30min' freq='10D'periods:固定時期,取值為整數或None'''# -----------------date = pd.date_range(start='20200528',periods=10,freq='10D')print(date)'''DatetimeIndex(['2020-05-28', '2020-06-07', '2020-06-17', '2020-06-27', ? ? ? ? ? ? ? '2020-07-07', '2020-07-17', '2020-07-27', '2020-08-06', ? ? ? ? ? ? ? '2020-08-16', '2020-08-26'], ? ? ? ? ? ? dtype='datetime64[ns]', freq='10D')'''# 根據closed參數選擇是否包含開始和結束時間closed=None,left包含開始時間,不包含結束時間,right與之相反。data_time =pd.date_range(start='2020-05-09',end='2020-05-14',closed='left')print(data_time)'''DatetimeIndex(['2020-05-09', '2020-05-10', '2020-05-11', '2020-05-12', ? ? ? ? ? ? ? '2020-05-13'], ? ? ? ? ? ? dtype='datetime64[ns]', freq='D')'''# 2. 時間序列在dataFrame中的作用# 可以將時間作為索引index = pd.date_range(start='20200101',periods=10)df = pd.Series(np.random.randint(0,10,size = 10),index=index)print(df)'''2020-01-01 ? 42020-01-02 ? 42020-01-03 ? 02020-01-04 ? 92020-01-05 ? 62020-01-06 ? 72020-01-07 ? 52020-01-08 ? 62020-01-09 ? 42020-01-10 ? 9Freq: D, dtype: int64'''# truncate這個函數將before指定日期之前的值全部過濾出去,after指定日期之后的值全部過濾出去.after = df.truncate(after='20200105')print(after)'''2020-01-01 ? 92020-01-02 ? 42020-01-03 ? 72020-01-04 ? 82020-01-05 ? 9Freq: D, dtype: int64'''# 接下來是對時間格式的處理,因為運行出來的結果較多,所以運行完一次,我們將print注釋# 創建一個含有一千行的時間序列,時間跨度從2019年到2021年long_ts = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2019',periods=1000))#print(long_ts)# 根據年份獲取result = long_ts['2020']#print(result)# 年份和日期獲取result = long_ts['2020-05']#print(result)# 使用切片result = long_ts['2020-05-01':'2020-05-06']# print(result)# 通過between_time()返回位于指定時間段的數據集index=pd.date_range("2020-03-17","2020-03-30",freq="2H")ts = pd.Series(np.random.randn(157),index=index)#print(ts.between_time("7:00","17:00"))# 這些操作也都適用于dataframeindex=pd.date_range('1/1/2020',periods=100)df = pd.DataFrame(np.random.randn(100,4),index=index)#print(df.loc['2020-04'])# 將時間戳轉化成時間格式?某一個時間到1970年01月01日 00:00:00 的秒數或者毫秒數# 時間戳是現在時間到1970年01月01日 00:00:00的毫秒數或者秒數,可以將時間格式化表示成一個數值,方便時間的計算# 獲取當前時間的時間戳import time #print(time.time()) #1590704235.606594#pd.to_datetime(1590704235.606594,unit='s')# 時區轉換:utc是協調世界時,時區是以UTC的偏移量的形式表示的# 查詢時區名字 選擇Asia/Shanghaiimport pytz#print(pytz.common_timezones)#pd.to_datetime(1590704235.606594,unit='s').tz_localize('UTC').tz_convert('Asia/Shanghai')# 處理一列df = pd.DataFrame([1590704235.606594, 1590704295.606594, 1590704355.606594],columns = ['time_stamp'])# 先賦予標準時區,再轉換到東八區#pd.to_datetime(df['time_stamp'],unit='s').dt.tz_localize('UTC').dt.tz_convert('Asia/Shanghai')# 處理中文格式日期#pd.to_datetime('2020年5月20日',format='%Y年%m月%d日')分組聚合
這一部分我們學習對DataFrame的數據按照相應的格式進行分組,使用函數groupby()。
# 分組import pandas as pd import numpy as npdf=pd.DataFrame({'name':['BOSS','Lilei','Lilei','Han','BOSS','BOSS','Han','BOSS'], ? ? ? ? ? ? ? ? ? ?'Year':[2018,2018,2018,2018,2019,2019,2019,2019], ? ? ? ? ? ? ? ? ? ?'Salary':[999999,20000,25000,3000,9999999,999999,3500,999999], ? ? ? ? ? ? ? ? ? ?'Bonus':[100000,20000,20000,5000,200000,300000,3000,400000]})display(df)''' ? name Year ? Salary ? Bonus0 ? BOSS 2018 ? 999999 1000001 Lilei 2018 ? 20000 ? 200002 Lilei 2018 ? 25000 ? 200003 ? Han 2018 ? ? 3000 ? 50004 ? BOSS 2019 9999999 2000005 ? BOSS 2019 ? 999999 3000006 ? Han 2019 ? ? 3500 ? 30007 ? BOSS 2019 ? 999999 400000'''# 根據name這一列進行分組group_by_name=df.groupby('name')print(type(group_by_name))# 查看分組print(group_by_name.groups)# 分組后的數量#print(group_by_name.count())''' # df分組后返回的是一個DataFrameGroupBy的對象,不能直接查看它{'BOSS': Int64Index([0, 4, 5, 7], dtype='int64'),'Han': Int64Index([3, 6], dtype='int64'),'Lilei': Int64Index([1, 2], dtype='int64')} ? ? ? Year Salary Bonusname ? ? ? ? ? ? ? ? ? ? ?BOSS ? ? 4 ? ? ? 4 ? ? 4Han ? ? ? 2 ? ? ? 2 ? ? 2Lilei ? ? 2 ? ? ? 2 ? ? 2'''# 查看分組的情況for name,group in group_by_name: ? ?print(name)# 組的名字 共三組 ? ?print(group)# 組具體內容'''BOSS ? name Year ? Salary ? Bonus0 BOSS 2018 ? 999999 1000004 BOSS 2019 9999999 2000005 BOSS 2019 ? 999999 3000007 BOSS 2019 ? 999999 400000Han name Year Salary Bonus3 Han 2018 ? 3000 ? 50006 Han 2019 ? 3500 ? 3000Lilei ? name Year Salary Bonus1 Lilei 2018 ? 20000 200002 Lilei 2018 ? 25000 20000'''# 可以選擇分組print(group_by_name.get_group('BOSS'))# 按照某一列進行分組, 將name這一列作為分組的鍵,對year進行分組group_by_name=df['Year'].groupby(df['name'])print(group_by_name.count())'''name Year ? Salary ? Bonus0 BOSS 2018 ? 999999 1000004 BOSS 2019 9999999 2000005 BOSS 2019 ? 999999 3000007 BOSS 2019 ? 999999 400000nameBOSS ? ? 4Han ? ? 2Lilei ? 2Name: Year, dtype: int64'''# 按照多列進行分組group_by_name_year=df.groupby(['name','Year'])for name,group in group_by_name_year: ? ?print(name)# 組的名字 ? ?print(group)# 組具體內容'''('BOSS', 2018) ? name Year Salary ? Bonus0 BOSS 2018 999999 100000('BOSS', 2019) ? name Year ? Salary ? Bonus4 BOSS 2019 9999999 2000005 BOSS 2019 ? 999999 3000007 BOSS 2019 ? 999999 400000('Han', 2018) name Year Salary Bonus3 Han 2018 ? 3000 ? 5000('Han', 2019) name Year Salary Bonus6 Han 2019 ? 3500 ? 3000('Lilei', 2018) ? name Year Salary Bonus1 Lilei 2018 ? 20000 200002 Lilei 2018 ? 25000 20000'''# 將某列數據按數據值分成不同范圍段進行分組(groupby)運算# 準備數據,生產100個年齡,從20-70歲df = pd.DataFrame({'Age': np.random.randint(20, 70, 100), ? ? ? ? ? ? ? ? 'Sex': np.random.choice(['M', 'F'], 100)})# print(df)age_groups = pd.cut(df['Age'], bins=[19,40,65,100]) # 將Age列切成幾個bins,分成了三個區間print(age_groups) ?# 查看分組print(df.groupby(age_groups).count()) # 分組統計# 按‘Age’分組范圍對性別(sex)進行分組統計print(pd.crosstab(age_groups, df['Sex']))'''Name: Age, Length: 100, dtype: categoryCategories (3, interval[int64]): [(19, 40] < (40, 65] < (65, 100]] ? ? ? ? ? Age SexAge ? ? ? ? ? ? ? ?(19, 40] ? 51 ? 51(40, 65] ? 43 ? 43(65, 100] ? 6 ? 6Sex ? ? ? ? F ? MAge ? ? ? ? ? ? ?(19, 40] ? 27 24(40, 65] ? 21 22(65, 100] ? 1 ? 5'''聚合函數對一組值執行計算,并返回單個值。
以下是常用的聚合函數:
| count | 分組中非NA值的數量 |
| sum | 非NA值的和 |
| median | 非NA值的算術中位數 |
| std | 標準差 |
| var | 方差 |
| min | 非NA值的最小值 |
| max | 非NA值的最大值 |
| prod | 非NA值的積 |
| first | 第一個非NA值 |
| last | 最后一個非NA值 |
| mad | 平均絕對偏差 |
| mode | 模 |
| abs | 絕對值 |
| sem | 平均值的標準誤差 |
| skew | 樣品偏斜度(三階矩) |
| kurt | 樣品峰度(四階矩) |
| quantile | 樣本分位數(百分位上的值) |
| cumsum | 累積總和 |
| cumprod | 累積乘積 |
| cummax | 累積最大值 |
| cummin | 累積最小值 |
? ?return smoker.sort_values(by=col)[-n:]
# [-n:]切片,負號表示從末尾往前取
print(df1.groupby('smoker').apply(top,col='weight',n=2))''' ? ? ? ? sex smoker age weightsmoker ? ? ? ? ? ? ? ? ? ? ? ? ?N ? ? 4 ? M ? ? N ? 1 ? ? 94 ? ? ? 1 ? F ? ? N ? 1 ? ? 100Y ? ? 2 ? M ? ? Y ? 0 ? ? 132 ? ? ? 3 ? F ? ? Y ? 1 ? ? 140'''分組案例
下面我們來對一個電影評論數據進行案例分析,公號留言回復 PandasMovie 即可獲取。
# 讀取數據并觀察data = pd.read_csv('pandas_movie.csv')print('數據的形狀:', data.shape)# 數據的形狀: (5043, 28)#print(data.head(5)) #發現索引4 有NaN# 處理缺失值data = data.dropna(how='any') # 將Nan去除print(data.head(5)) # 索引4被去除# 我們來分析一下導演和票房總收入(gross)的關系 通過分組排序來觀察是否票房高的電影由知名導演拍攝# 按照導演分組計算票房總收入group_director = data.groupby(by='director_name')['gross'].sum()print(group_director)# ascending升降序排列,True升序result = group_director.sort_values()print(type(result)) # 查看分組后結果的數據的數據類型是Series,一維數組print(result) # 可以看到高票房的導演# 電影產量年份趨勢from matplotlib import pyplot as pltimport random# 按照年分分析電影產量的情況,以及電影的名稱movie_years = data.groupby('title_year')['movie_title']print(movie_years.count())print(movie_years.count().index.tolist()) # 將索引列也就是年份的索引取出,并轉換成列表格式print(movie_years.count().values) # 電影的數量x = movie_years.count().index.tolist()y = movie_years.count().values plt.figure(figsize=(20,8),dpi=80)plt.plot(x,y)plt.show()運行結果:
寫在后面:
今天學習是Pandas庫的下半部分~
周末快要到了,周末我們的學習計劃會停一停~
堅持學習和輸出哦~
記得打卡,在群里分享你的代碼和筆記~
好文章,我在看?
總結
以上是生活随笔為你收集整理的list取数据_Day.5利用Pandas做数据处理(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LSGO软件技术团队对外技术交流
- 下一篇: 全球芯片刚要降价 台积电突然警告:先进工