3.1 內(nèi)省Excel工作薄
使用xlrd和xlwt擴展包,確定工作簿中工作表的數(shù)量斩郎、名稱和每個工作表中行列的數(shù)量脑融。
1excel_introspect_workbook.py
#!/usr/bin/env python3
import sys
from xlrd import open_workbook
input_file = sys.argv[1]
workbook = open_workbook(input_file)
print('Number of worksheets: ', workbook.nsheets)
for worksheet in workbook.sheets():
print("Worksheet name:", worksheet.name, "\tRows:",\
worksheet.nrows, "\tColumns:", worksheet.ncols)
導入xlrd模塊open_workbook函數(shù)讀取和分析Excel文件。
for循環(huán)在所有工作表之間迭代缩宜,workbook對象的sheets方法可以識別出工作簿中所有的工作表肘迎。
print語句使用worksheet對象的name屬性確定每個工作表名稱,使用nrows和ncols屬性確定每個工作表中行與列的數(shù)量锻煌。
輸出結(jié)果:
Number of worksheets: 3
Worksheet name: january_2013 Rows: 7 Columns: 5
Worksheet name: february_2013 Rows: 7 Columns: 5
Worksheet name: march_2013 Rows: 7 Columns: 5
3.2 處理單個工作表
3.2.1 讀寫Excel文件
使用pandas分析Excel文件
pandas_read_and_write_excel.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, sheet_name='january_2013')
writer = pd.ExcelWriter(output_file)
data_frame.to_excel(writer, sheet_name='jan_13_output', index=False)
writer.save()
3.2.2 篩選特定行
行中的值滿足某個條件
用pandas篩選出Sale Amount大于$1400.00的行妓布。
pandas_value_meets_condition.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, 'january_2013', index_col=None)
data_frame_value_meets_condition = \
data_frame[data_frame['Sale Amount'].astype(float) > 1400.0]
writer = pd.ExcelWriter(output_file)
data_frame_value_meets_condition.to_excel(\
writer, sheet_name='jan_13_output', index=False)
writer.save()
行中的值屬于某個集合
用pandas篩選出購買日期屬于集合(01/24/2013-01/31/2013)的行。
pandas提供isin函數(shù)檢驗一個特定值是否在一個列表中
pandas_value_in_set.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, 'january_2013', index_col=None)
important_dates = ['01/24/2013', '01/31/2013']
data_in_set = data_frame[data_frame['PurchaseDate']\
.isin(important_dates)]
writer = pd.ExcelWriter(output_file)
data_in_set.to_excel(writer, sheet_name='jan_13_output', index=False)
writer.save()
行中的值匹配于特定模式
用pandas篩選出客戶姓名以大寫字母J開頭的行宋梧。
pandas_value_matches_pattern.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, 'january_2013', index_col=None)
data_frame_value = data_frame[data_frame['Customer Name']\
.str.startswith("J")]
writer = pd.ExcelWriter(output_file)
data_frame_value.to_excel(writer, sheet_name='jan_13_output', index=False)
writer.save()
3.2.3 選取特定列
有兩種方法可以在Excel文件中選取特定的列:
- 使用列索引值
- 使用列標題
使用列索引值
用pandas設置數(shù)據(jù)框匣沼,在方括號中列出要保留的列的索引值或名稱(字符串)。設置數(shù)據(jù)框和iloc函數(shù)捂龄,同時選擇特定的行與特定的列释涛。如果使用iloc函數(shù)來選擇列加叁,那么就需要在列索引值前面加上一個冒號和一個逗號,表示為這些特定的列保留所有的行枢贿。
pandas_column_by_index.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file =sys.argv[2]
data_frame = pd.read_excel(input_file, 'january_2013', index_col=None)
data_frame_index = data_frame.iloc[:, [1:4]]
writer = pd.ExcelWriter(output_file)
data_frame_index.to_excel(writer, sheet_name='jan_13_out', index=False)
writer.save()
使用列標題
用pandas基于列標題選取Customer ID和Purchase Date列的兩種方法:
- 在數(shù)據(jù)框名稱后面的方括號中將列名以字符串方式列出殉农。
- 用loc函數(shù),在列標題列表前面加上一個冒號和一個逗號局荚,表示為這些特定的列保留所有行超凳。
pandas_column_by_name.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, 'january_2013', index_col=None)
data_frame_column = data_frame.iloc[:, ['Customer ID', 'Purchase Date']]
writer = pd.ExcelWriter(output_file)
data_frame_column.to_excel(writer, sheet_name='jan_13_output', index=False)
writer.save()
3.3 讀取工作簿中的所有工作表
3.3.1 在所有工作表中篩選特定行
pandas通過在read_excel函數(shù)中設置sheetname=None,可以一次性讀取工作簿中的所有工作表耀态。
pandas將所有工作表讀入數(shù)據(jù)框字典轮傍,字典中的鍵就是工作表的名稱,值就是包含工作表中數(shù)據(jù)的數(shù)據(jù)框首装。所以创夜,通過在字典的鍵和值之間迭代,可以使用工作簿中所有的數(shù)據(jù)仙逻。
當在每個數(shù)據(jù)框中篩選特定行時驰吓,結(jié)果是一個新的篩選過的數(shù)據(jù)框,所以可以創(chuàng)建一個列表保存這些篩選過的數(shù)據(jù)框系奉,然后將它們連接成一個最終數(shù)據(jù)框檬贰。
在所有工作表中篩選出銷售額大于$2000.00的所有行。
pandas_value_ meets_condition_all_worksheets.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, sheet_name=None, index_col=None)
row_output = []
for worksheet_name, data in data_frame.items():
row_output_append(data[data['Sale Amount'].astype(float) > 2000.0])
filtered_rows = pd.concat(row_output, axis=0, ignore_index=True)
writer = pd.ExcelWriter(output_file)
filtered_rows.to_excel(writer, sheet_name='sale_amount_gt2000', index=False)
writer.save()
3.3.2 在所有工作表中選取特定列
有兩種方法可以從工作表中選取一組列:
- 使用列索引值
- 使用列標題
在所有工作表中選取Customer Name和Sale Amount列
用pandas的read_excel函數(shù)將所有工作表讀入字典缺亮。然后翁涤,用loc函數(shù)在每個工作表中選取特定的列,創(chuàng)建一個篩選過的數(shù)據(jù)框列表萌踱,并將這些數(shù)據(jù)框連接在一起葵礼,形成一個最終數(shù)據(jù)框。
pandas_column_ by_name_all_worksheets.py
#!/usr/bin/env python3
import pandas as pd
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
data_frame = pd.read_excel(input_file, sheet_name=None, index_col=None)
column_output = []
for worksheet_name, data in data_frame.items():
column_output.append(data.loc[:, ['Customer Name', 'Sale Amount']])
selected_columns = pd.concat(column_output, axis=0, ignore_index=True)
writer = pd.ExcelWriter(output_file)
selected_columns.to_excel(writer, sheet_name='selected_columns_all_worksheets',\
index=False)
writer.save()
3.4 在Excel工作簿中讀取一組工作表
在一組工作表中篩選特定行
用pandas在工作簿中選擇一組工作表并鸵,在read_excel函數(shù)中將工作表的索引值或名稱設置成一個列表鸳粉。創(chuàng)建索引值列表my_ sheets,在read_excel函數(shù)中設定sheetname等于my_sheets园担。想從第一個和第二個工作表中篩選出銷售額大于$1900.00 的行届谈。
pandas_value_meets_condition_set_of_worksheets.py
#!/usr/bin/env python
import pandas as pd
import sys
input_file = sys.argv[1]
output_file =sys.argv[2]
my_sheets = [0,1]
threshold = 1900.0
data_frame = pd.read_excel(input_file, sheet_name=my_sheets, index_col=None)
row_list = [ ]
for worksheet_name, data in data_frame.items():
row_list.append(data[data['Sale Amount'].astype(float) > threshold])
filtered_rows = pd.concat(row_list, axis=0, ignore_index=True)
writer = pd.ExcelWriter(output_file)
filtered_rows.to_excel(writer, sheet_name='set_of_worksheets', index=False)
writer.save()
3.5 處理多個工作簿
3.5.1 工作表計數(shù)以及每個工作表中的行列計數(shù)
在開始處理工作表之前,獲取關于工作表的描述性信息非常重要粉铐。
想知道一個文件夾中工作簿的數(shù)量疼约,每個工作簿中工作表的數(shù)量卤档,以及每個工作表中行與列的數(shù)量:
12excel_introspect_all_ workbooks.py
#!/usr/bin/env python3
import glob
import os
import sys
from xlrd import open_work
input_directory = sys.argv[1]
workbook_counter = 0
for input_file in glob.glob(os.path.join(input_directory, '*.xls*')):
workbook = open_workbook(input_file)
print('Workbook: %s' % os.path.basename(input_file))
print('Number of worksheets: %d' % workbook.nsheets)
for worksheet in workbook.sheets():
print('Worksheet name:', worksheet.name, '\tRows:',\
worksheet.nrows, '\tColumns:', worksheet.nclos)
workbook_counter += 1
print('Number of Excel workbooks: %d' % (workbook_counter))
導入Python內(nèi)置的glob模塊和os模塊蝙泼,使用其中的函數(shù)識別和解析待處理文件的路徑名。
使用Python內(nèi)置的glob模塊和os模塊劝枣,創(chuàng)建要處理的輸入文件列表汤踏,并對輸入文件列表應用for循環(huán)织鲸,對所有要處理的工作簿進行迭代。
3.5.2 從多個工作簿中連接數(shù)據(jù)
pandas提供concat函數(shù)連接數(shù)據(jù)框溪胶。
- 如果想把數(shù)據(jù)框一個一個地垂直堆疊搂擦,設置參數(shù)axis=0。
- 如果想把數(shù)據(jù)框一個一個地平行連接哗脖,設置參數(shù)axis=1瀑踢。
如果要基于某個關鍵字列連接數(shù)據(jù)框,pandas的merge函數(shù)提供類似SQL join的操作才避。
用pandas將多個工作簿中所有工作表的數(shù)據(jù)垂直連接成一個輸出文件
pandas_concat_data_from_multiple_workbook.py
#!/usr/bin/env python3
import pandas as pd
import glot
import os
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
all_workbooks = glob.glob(os.path.join(input_path, '*.xls*'))
data_frames = [ ]
for workbook in all_workbooks:
all_workbooks = pd.read_excel(workbook, sheet_name=None, index_col=None)
for worksheet_name, data in all_worksheets.items():
data_frames.append(data)
all_data_concatenated = pd.concat(data_frame, axis=0, ignore_index=True)
writer = pd.ExcelWriter(output_file)
all_data_concatenated.to_excel(writer, sheet_name='all_data_all_workbooks',\
index=False)
writer.save()
3.5.3 為每個工作簿和工作表計算總數(shù)和均值
pandas在多個工作簿間迭代橱夭,在工作簿級和工作表級計算統(tǒng)計量。為工作簿的每個工作表計算統(tǒng)計量桑逝,并將結(jié)果連接成一個數(shù)據(jù)框棘劣。
接下來,計算工作簿級的統(tǒng)計量楞遏,將它們轉(zhuǎn)換成一個數(shù)據(jù)框茬暇,然后通過基于工作簿名稱的左連接將兩個數(shù)據(jù)框合并在一起,并將結(jié)果數(shù)據(jù)框添加到一個列表中寡喝。
當所有工作簿級的數(shù)據(jù)框都進入列表后糙俗,將這些數(shù)據(jù)框連接成一個獨立數(shù)據(jù)框,并寫入輸出文件拘荡。
pandas_sum_average_multiple_workbook.py
#!/usr/bin/env python3
import pandas as pd
import glob
import os
import sys
input_path = sys.argv[1]
output_file = sys.argv[2]
all_workbooks = glob.glob(os.path.join(input_path, '*.xls*'))
data_frames = [ ]
for workbook in all_workbooks:
all_workbooks = pd.read_excel(workbook, sheet_name=None, index_col=None)
workbook_total_sales = [ ]
workbook_number_of_sales = [ ]
worksheet_data_frames = [ ]
worksheets_data_frame = None
workbook_data_frame = None
for worksheet_name, data in all_worksheets.items():
total_sales = pd.DataFrame([float(str(value).strip('$').replace(\
',',' '))
for value in data.loc[:, 'Sale Amount']]).sum()
number_of_sales = len(data.loc[:, 'Sale Amount'])
average_sales = pd.DataFrame(total_sales / number_of_sales)
workbook_total_sales.append(total_sales)
workbook_number_of_sales.append(number_of_sales)
data = {'workbook': os.path.basename(workbook),
'worksheet': worksheet_name,
'worksheet_total': total_sales,
'wprksheet_average': average_sales}
worksheet_Data_frame.append(pd.DataFrame(data, \
columns=['workbook', ''worksheet, \
'worksheet_total', 'worksheet_average']))
worksheets_data_frame = pd.concat(\
worksheet_data_frames, axis=0, ignore_index=True
workbook_total = pd.DataFrame(workbook_total_sales).sum()
workbook_total_number_of_sales = pd.DaraFrame(\
workbook_numbwe_of_sales).sum()
workbook_average = pd.DataFrame(\
workbook_total / workbook_total_number_of_sales)
work_stats = {'workbook': os.path.basename(workbook),
'workbook_total'}: workbook_total,
'workbook_average': workbook_average}
workbooks_stats = pd.DataFrame(workbook_stats, columns=\
['workbook', 'workbook_total', 'workbook_average'])
workbook_data_frame = pd.merge(worksheets_data_frame, workbook_stats, \
on='workbook', how='left')
data_frames.append(workbook_data_frame)
all_data_concatenated = pd.concat(data_frames, axis=0, ignore_index=True)
writer = pd.ExcelWriter(output_file)
all_data_concatenated.to_excel(writer, sheet_name='sums_and_averages', index=False)
writer.save()