pandas 玩转 Excel 操作总结
Python 操作Excel操作總結,包括Series和Data Frame的互轉、使用pandas讀取Excel表格、python讀取多個數據表、python合并多個工作表以及寫入Excel文件
pandas是一款基于NumPy的數據分析工具。它提供了大量的能使我們快捷處理數據的方法。
數據科學線性代數公式匯總
隨筆記錄所的所學,此博客為我記錄文章所用,發布到此,僅供網友閱讀參考。作者:北山啦
# -*- coding:utf-8 -*- # @Address:https://beishan.blog.csdn.net/ # @Author:北山啦文章目錄
- Series和Data Frame的互轉
- 使用pandas讀取Excel表格
- 讀取多個數據表
- 合并多個工作表
- 寫入Excel文件
常用數據類型
- Series:一維數組,與NumPy中的一維數組相似,和Python自身的list也相似。區別自語Series中的數據只能是一種數據,而list中的數據可以不一樣
- Time-Series:以時間為索引的Series
- DataFrame:二維的表格型數據結構。經常用于處理Excel表格數據等,這也是我們本節課會重點講的內容
- Panel:三維數組(0.25版本后,統一使用xarray,不再支持Panel)
Series和Data Frame的互轉
- 利用to_frame()實現Series轉DataFrame
- 利用squeeze()實現單列數據DataFrame轉Series
| 北山啦 |
| 關注 |
| 點贊 |
使用pandas讀取Excel表格
在pandas中,讀取Excel非常簡單,它只有一個方法:readExcel(),但是的參數非常多
主要常用的參數,我們先對其進行了解:
- io:一般指定excel文件路徑就可以了。也可以是其他Excel讀取對象如ExcelFile、xlrd.Book等
- sheet_name:用于指定工作表(sheet)名稱。可以是數字(工作表從0開始的索引)
- header:指定作為列名的行,默認為0,即第一行為列名。如果數據不含列名,則設為None
- names:指定新的列名列表。列表中元素個數和列數必須一致
- index_col:指定列為索引列,默認None指的是索引為0的第一列為索引列
- usecols:要解析數據的列,可以是int或者str的列表,也可以是以逗號分隔的字符串(pandas 0.24新增功能),例如:”A:F”,表示從A列到F列,”A,C,F”表示A、C、F三列,還可以寫成”A,C,F,K:Q”
- dtype:各列的數據類型,例如:{‘a’: np.float64, ‘b’: np.int32}
- converters:用于轉換各列數據的函數的字典數據,例如:{‘a’: func_1, ‘b’: func_2}
| OLIVER. | 23 | 7653 |
| HARRY. | 45 | 8799 |
| GEORGE. | 34 | 9800 |
| NOAH. | 54 | 12880 |
| JACK. | 34 | 3600 |
我們先來看一下取回的數據的數據類型是什么。
print(type(sheet)) <class 'pandas.core.frame.DataFrame'>可以看到,它就是我們前面提到的DataFrame數據。,直接通過它的列名稱來獲取即可,比如,要獲得所有的工資信息,可以如下:
print(sheet['工資']) 0 7653 1 8799 2 9800 3 12880 4 3600 5 3800 6 8976 7 12000 8 8900 9 7688 10 6712 11 9655 12 6854 13 8122 14 6788 15 8830 Name: 工資, dtype: int64可以看到它的所有的數據都列出來了,并且這一列數據的數據類型是int64,即64位整型。
得到這一列數據后,我們可以對它進行處理。
或者將它轉換成列表后再處理:
salaries = list(sheet['工資']) print(salaries) [7653, 8799, 9800, 12880, 3600, 3800, 8976, 12000, 8900, 7688, 6712, 9655, 6854, 8122, 6788, 8830]計算大家的平均工資:
sum = 0 for i in salaries:sum += iprint(f"總工資:{sum}") ave = sum / len(salaries) print(f"平均工資:{ave}") 總工資:131057 平均工資:8191.0625我們也可以對求和的方法,使用lambda表達式(匿名函數)結合reduce()函數進行。reduce()函數會對列表、元組等可遍歷的元素依次進行運算:將第一個元素和第二個元素進行運算,并將結果和第三個元素進行運算,直到最后一個元素。
import functools sum = functools.reduce(lambda x, y: x + y, salaries) print(sum) 131057我們可以使用read_excel中的usecols參數,通過它指定我們需要讀取數據的列,它接收字符串或者整數列表格式的數據,列表中列出我們想要取出數據的列的名稱或者索引。
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx", usecols=[2]) sheet| 7653 |
| 8799 |
| 9800 |
| 12880 |
| 3600 |
| 3800 |
| 8976 |
| 12000 |
| 8900 |
| 7688 |
| 6712 |
| 9655 |
| 6854 |
| 8122 |
| 6788 |
| 8830 |
或者:
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx", usecols=['工資']) sheet| 7653 |
| 8799 |
| 9800 |
| 12880 |
| 3600 |
| 3800 |
| 8976 |
| 12000 |
| 8900 |
| 7688 |
| 6712 |
| 9655 |
| 6854 |
| 8122 |
| 6788 |
| 8830 |
如果想在讀取數據的時候,將原來的列的名字改成其他名字,則可以使用names參數指定為其他列名:
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx", names=['name','age','salary']) sheet| OLIVER. | 23 | 7653 |
| HARRY. | 45 | 8799 |
| GEORGE. | 34 | 9800 |
| NOAH. | 54 | 12880 |
| JACK. | 34 | 3600 |
| JACOB. | 32 | 3800 |
| MUHAMMAD. | 51 | 8976 |
| LEO. | 46 | 12000 |
| Harper. | 42 | 8900 |
| Evelyn. | 38 | 7688 |
| Ella. | 33 | 6712 |
| Avery. | 26 | 9655 |
| Scarlett. | 37 | 6854 |
| Madison. | 41 | 8122 |
| Lily. | 54 | 6788 |
| Eleanor. | 28 | 8830 |
需要注意的是,此時,我們如果要對這個DataFrame進行操作,就需要使用新的列名了。 如果我們想在取出工資數據的時候,以“¥12,345”的格式顯示,則可以在獲取數據的時候,就指定轉換函數:
import pandas as pd def formatsalary(num):return f"¥{format(num,',')}"sheet = pd.read_excel(io="測試數據.xlsx", usecols=['工資'],converters={'工資':formatsalary}) sheet| ¥7,653 |
| ¥8,799 |
| ¥9,800 |
| ¥12,880 |
| ¥3,600 |
| ¥3,800 |
| ¥8,976 |
| ¥12,000 |
| ¥8,900 |
| ¥7,688 |
| ¥6,712 |
| ¥9,655 |
| ¥6,854 |
| ¥8,122 |
| ¥6,788 |
| ¥8,830 |
上面通過converters指定了“工資”列,使用formatsalary函數來處理,所以取出來的數據就已經處理過的了。當然,我們也可以取出來后在對其進行格式化。
其他的參數,大家可以自己進行試驗。下面我們再來看一下,假設我要取出所有大于等于8000的工資,該如何進行處理呢?我們可以使用按照條件來獲取DataFrame的行數據:
| 8799 |
| 9800 |
| 12880 |
| 8976 |
| 12000 |
| 8900 |
| 9655 |
| 8122 |
| 8830 |
如果想取得工資大于等于8000小于等于10000的數據:
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx") high_salary = sheet[(sheet['工資'] >= 8000) & (sheet['工資'] <=10000)] high_salary| HARRY. | 45 | 8799 |
| GEORGE. | 34 | 9800 |
| MUHAMMAD. | 51 | 8976 |
| Harper. | 42 | 8900 |
| Avery. | 26 | 9655 |
| Madison. | 41 | 8122 |
| Eleanor. | 28 | 8830 |
如果只想顯示符合條件的姓名和工資,則可以通過列表的方式指定要顯示的列:
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx") high_salary = sheet[(sheet['工資'] >= 8000) & (sheet['工資'] <=10000)][['姓名','工資']] high_salary| HARRY. | 8799 |
| GEORGE. | 9800 |
| MUHAMMAD. | 8976 |
| Harper. | 8900 |
| Avery. | 9655 |
| Madison. | 8122 |
| Eleanor. | 8830 |
讀取多個數據表
在上面的例子中,雖然在“測試數據.xlsx”文件中包含了兩個數據表(sheet),但它只讀取了第一個數據表的內容,如果我想把兩個數據表數據都讀取出來該怎么辦呢?可以指定sheet_name參數,它接收字符串、數字、字符串或數字列表以及None。如果指定為None,則返回所有數據表數據。默認為0,即返回第一個數據表數據。
import pandas as pd sheet = pd.read_excel(io="測試數據.xlsx", sheet_name=[0, 1]) sheet {0: 姓名 年齡 工資0 OLIVER. 23 76531 HARRY. 45 87992 GEORGE. 34 98003 NOAH. 54 128804 JACK. 34 36005 JACOB. 32 38006 MUHAMMAD. 51 89767 LEO. 46 120008 Harper. 42 89009 Evelyn. 38 768810 Ella. 33 671211 Avery. 26 965512 Scarlett. 37 685413 Madison. 41 812214 Lily. 54 678815 Eleanor. 28 8830,1: 姓名 年齡 工資0 張三 39 150001 李四 43 160002 李雷 25 68003 韓梅梅 28 23000}可以看到,得到了兩個數據表的數據。此時要得到數據表中的數據,就需要先通過sheet[0]、sheet[1]得到第一個數據表的所有數據,再在這個數據表數據中對數據進行處理了,例如:
sheet[1]| 張三 | 39 | 15000 |
| 李四 | 43 | 16000 |
| 李雷 | 25 | 6800 |
| 韓梅梅 | 28 | 23000 |
如果用的是數據表的名字,則應該寫成sheet[‘甲公司’]。
如果我們想把這兩個數據表的數據合并到一起,可以使用pandas中的concat()函數:
| 張三 | 39 | 15000 |
| 李四 | 43 | 16000 |
| 李雷 | 25 | 6800 |
| 韓梅梅 | 28 | 23000 |
| OLIVER. | 23 | 7653 |
| HARRY. | 45 | 8799 |
| GEORGE. | 34 | 9800 |
| NOAH. | 54 | 12880 |
| JACK. | 34 | 3600 |
| JACOB. | 32 | 3800 |
| MUHAMMAD. | 51 | 8976 |
| LEO. | 46 | 12000 |
| Harper. | 42 | 8900 |
| Evelyn. | 38 | 7688 |
| Ella. | 33 | 6712 |
| Avery. | 26 | 9655 |
| Scarlett. | 37 | 6854 |
| Madison. | 41 | 8122 |
| Lily. | 54 | 6788 |
| Eleanor. | 28 | 8830 |
這里ignore_index的意思是忽略各自的索引,統一使用新的索引。
合并多個工作表
多個EXCECL合并到一個工作表中,Python來幫你實現
# -*- coding:utf-8 -*- # @Address:https://beishan.blog.csdn.net/ # @Author:北山啦 import pandas as pd import os path = r"五省PM2.5\archive" dfs,index = [],0 for i in os.listdir(path):dfs.append(pd.read_csv(os.path.join(path,i)))print(f"正在合并{index+1}工作表")index += 1 df = pd.concat(dfs) df.to_csv("數據匯總.csv",index=False) 正在合并1工作表 正在合并2工作表 正在合并3工作表 正在合并4工作表 正在合并5工作表 正在合并6工作表 正在合并7工作表寫入Excel文件
可以將DataFrame數據寫入到一個新的Excel文件中,例如,我們可以將上面合并的兩個Excel數據表數據,寫入到新的Excel文件中:
df = pd.DataFrame(st) df.to_excel("合并工資報表.xlsx")這里我們使用DataFrame上的to_excel()方法將數據寫入到Excel文件中。它的原型是:to_excel(self, 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:需要指定一個寫入的文件,可以是字符串或者ExcelWriter對象
- sheet_name:寫入的工作表名稱,是一個字符串,默認為’Sheet1’
- na_rep:當沒有數據的時候,應該填入的默認值,默認為空字符串
- float_format:浮點數格式,默認為None。可以按照float_format="%.2f"這樣的方式指定
- columns:指定寫入的列名順序,是一個列表。
- header:是否有表頭,默認為True,可以是布爾類型或者字符串列表。
- index:是否加上行索引,默認為True。
- index_label:索引標簽,可以是字符串或者列表,默認為None。
- startrow:插入數據的起始行,默認為0。
- startcol:插入數據的其實列,默認0
- engine:使用的寫文件引擎,例如:‘openpyxl’ 、 ‘xlsxwriter’
當然,我們也可以不限于將一個Excel表中的數據寫入到另一個Excel文件,我們自己在程序中運行得到的數據,也可以將其組織成DataFrame后,寫入到Excel文件中。
看看是不是寫入到文件了:
f = pd.read_excel("員工表.xlsx") f| 0 | 李雷 | 31 |
| 1 | 韓梅梅 | 22 |
| 2 | 小明 | 30 |
| 3 | 張三 | 49 |
| 4 | 李四 | 38 |
| 5 | 王五 | 33 |
可以看到,確實已經寫入進去了。
那如果要寫多個數據到一個Excel文件的多個數據表(sheet)中,該怎么處理呢?此時可以使用下面的方法。
看看是不是已經寫入到文件了:
sheet = pd.read_excel(io="Employees.xlsx", sheet_name=None) sheet {'國內員工': 姓名 年齡0 李雷 311 韓梅梅 222 小明 303 張三 494 李四 385 王五 33,'外籍員工': Names Age0 Andrew 421 Tomas 372 Larry 393 Sophie 354 Sally 295 Simone 27}但是仔細看的話,會發現上面的外籍員工這個數據表,字段Names和Age反了,這是因為DataFrame自動按照字母順序給我們排序了。要避免這種情況,需要在to_excel()中加上columns來指定表頭字段順序:
df1 = pd.DataFrame({'姓名':['李雷', '韓梅梅', '小明','張三', '李四', '王五'],'年齡':[31, 22, 30, 49, 38, 33]})df2 = pd.DataFrame({'Names': ['Andrew', 'Tomas', 'Larry','Sophie', 'Sally', 'Simone'],'Age':[42, 37, 39, 35, 29, 27]})dfs = {'國內員工':df1, '外籍員工':df2} cols = {"國內員工":['姓名', '年齡'],"外籍員工":['Names','Age']} # 指定列名順序 writer = pd.ExcelWriter('Employees.xlsx', engine='xlsxwriter')for sheet_name in dfs.keys():dfs[sheet_name].to_excel(writer, sheet_name=sheet_name, index=False, columns = cols[sheet_name])writer.save()再來看看現在是否正確:
sheet = pd.read_excel(io="Employees.xlsx", sheet_name=None) sheet {'國內員工': 姓名 年齡0 李雷 311 韓梅梅 222 小明 303 張三 494 李四 385 王五 33,'外籍員工': Names Age0 Andrew 421 Tomas 372 Larry 393 Sophie 354 Sally 295 Simone 27}現在沒問題了。
還可以使用前面讀寫文件的時候的with … 這種方式。
上面的方式,會覆蓋原來的文件內容。如果要在原有的Excel表中加上一個新的數據表(sheet),可以通過下面的方式:
可以看到,在原來的Excel文件中,已經加入了“候補員工”這個數據表。加入需要在某個數據表中加入數據(append),可以使用下面方式:
from openpyxl import load_workbook book = load_workbook("Employees.xlsx") # 加載原有的數據到Workbookdf4 = pd.DataFrame({'Names': ['Moore'],'Age':[38]})with pd.ExcelWriter('Employees.xlsx',engine='openpyxl') as writer: writer.book = book # 讓writer加入原來的3個workbookwriter.sheets = {ws.title: ws for ws in book.worksheets}start_row = writer.sheets['候補員工'].max_rowdf4.to_excel(writer, sheet_name='候補員工', index=False, columns=['Names', 'Age'], startrow=start_row,header=False)writer.save()這里的要點是:使用startrow指定要插入數據的文字,這里還要注意我們是往某個已經存在的數據表插入數據,所以要指定正確的sheet_name,還有就是為了避免重復的表頭,將header設置成False。
import pandas as pd sheet = pd.read_excel(io="Employees.xlsx", sheet_name=None) sheet {'國內員工': 姓名 年齡0 李雷 311 韓梅梅 222 小明 303 張三 494 李四 385 王五 33,'外籍員工': Names Age0 Andrew 421 Tomas 372 Larry 393 Sophie 354 Sally 295 Simone 27,'候補員工': Names Age0 Judy 271 Moore 38}到這里就結束了,如果對你有幫助,歡迎點贊關注評論,你的點贊對我很重要。
總結
以上是生活随笔為你收集整理的pandas 玩转 Excel 操作总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 中查询余额怎么写_如何调用中国
- 下一篇: 常用搜索引擎使用技巧