iT邦幫忙

1

[Python]輸出結果和自己本來所想的不一樣

  • 分享至 

  • xImage

各位前輩好,下面為我程式的敘述
其實到中途都跟我原本的想法一致(不斷用print()做結果確認)
但是到了最後一兩步就出了差錯,是否能幫小弟我確認程式碼哪裡出問題了嗎?

"""
此程式的作用
1. 讀取指定資料夾下的所有.xlsx、.xls以及.ods檔案
2. 讀取的檔案內容作結合
3. 依據特定欄位列(型號)內容做升冪排序
4. 針對其他欄位列(規格)的內容做字串切割
5. 字串切割後把原本的欄位列去除,並把切割後的資料放到資料最後端結合
6. 將切割後的資料的欄位更改名稱(不更改名稱的話會變成0、1、2之類)
7. 輸出成新的Excel檔案
"""
import glob
import pandas as pd

# 分別設定來源檔案路徑以及輸出檔案的路徑
import_folder_path = 'D:/automatic/final'
export_file_path = 'D:/excelprocess'

# 讀取來源資料夾內所有的.xlsx、.xls以及.ods檔案
path1 = import_folder_path + '/' + '*.xlsx'
path2 = import_folder_path + '/' + '*.xls'
path3 = import_folder_path + '/' + '*.ods'
file_path = glob.glob(path1)+glob.glob(path2)+glob.glob(path3)

# 將所有檔案資料結合(會以檔案名排序優先讀取)
df_concat = pd.DataFrame()
for i in file_path:
    df_read_excel = pd.read_excel(i)
    df_concat = pd.concat([df_read_excel, df_concat])

# 按照合併Excel表格欄位裡「型號」的內容欄位做升冪
df_sort = df_concat.sort_values(by='型號', ascending=True)

# 針對「規格」列的*符號做切割並延展成其他列
df2 = df_sort['規格'].str.split('*', expand=True)

# 刪除已排列後(df_sort)的Dataframe裡面的「規格」列後,並在尾端加入文字分割處理後的內容
df3 = df_sort.drop('規格', axis=1).join(df2)

'''
將原本的規格列刪除後,將列名更改名稱分別為「長」、「寬」、「高」
此處有兩種做法
方法1:只要填入分割成幾列就填入幾欄
方法2:全部有幾欄就要填幾個欄位名稱
'''
# df3.rename(columns={0: '長', 1: '寬', 2: '高'}, inplace=True)
df3.columns = ['型號', '數字', '長', '寬', '高']

'''
調動欄位顯示的方式
dfdisplay = df3.loc[:, ['數字', '型號', '寬', '長', '高']]
'''

# 輸出為xlsx檔案
df3.to_excel(export_file_path+'/'+'MultiFileSplitProcess.xlsx', index=False)

其實到df2為止都沒問題(有使用print(df2)確認內容)
但是到了下面做結合時(df3)就出現問題了

所謂的問題是,原本整個資料僅有28行資料,但是不知道為什麼在print(df3)的時候
竟然會暴增至134行資料(有些資料重複)
不知道這是什麼狀況?

※附帶一題,如果只有讀取單一檔案的話,是不會發生這問題的,但是在讀取多個檔案才有這樣多出資料

記得做好預設清空,不要讓上一個檔案拿到的東西帶到下一個。
我只提示這樣。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
Peter
iT邦新手 4 級 ‧ 2022-05-05 10:07:28
最佳解答

因為你的資料來源有3個(或以上),在join過後產生資料暴增或資料重複,通常是join過程中出現邏輯錯誤,以你的case我覺得比較可能是index重複的問題導致。

建議排查以下:
方法一、
rest_index 讓後續的join on在正確的匹配上

# 按照合併Excel表格欄位裡「型號」的內容欄位做升冪
df_sort = df_concat.sort_values(by='型號', ascending=True)

# rest_index 確保後續的join可以on在正確的匹配上
df_sort.reset_index(drop=True, inplace=True)

方法二、
使用merge並且指定left_on及right_on,來取代未指定任何欄位的join

rucifa iT邦新手 5 級 ‧ 2022-05-05 10:14:44 檢舉

感謝前輩的分享,的確按照方法1就可行了
只是沒想到單一檔案不會有錯誤,但是多個檔案結合時會有這樣狀況發生

只不過好奇的是,我之前也有練習將多檔案全部讀入,也同樣會有index重複狀況
但似乎沒有發生類似這次的事情(或許不像這個的練習直接對DataFrame直接做更動?)

Peter iT邦新手 4 級 ‧ 2022-05-05 10:41:35 檢舉

雖然這次問題是index重複問題所導致,但我認為關鍵的問題不是index的問題,而是使用neture join的方式本身就是有風險的,並且如果對於join的預設值不了解就直接使用的話,通常就会产生不如預期的结果,沒出問題就只是運氣好而已。

如果後續你仍然會進行資料處理的工作,我會建議深入去了解join與merge,在不同資料集的left、inner、outer等等的操作上有甚麼區別。

做為學習機會,建議你可以研究看看這次的case,left join on在重複的資料上(如重複index number)為何會產生資料暴增的問題,相信對於了解join這功能會很有幫助。

rucifa iT邦新手 5 級 ‧ 2022-05-05 10:50:10 檢舉

好的,非常感謝指教!

0
rofellos
iT邦新手 2 級 ‧ 2022-05-05 10:01:31

df2 = df_sort['規格'].str.split('*', expand=True)
這步作錯導致後續join後不合預期

1.了解join的規則,修改df2的資料內容
2.或不透過john,直接改df_sort['規格']的內容

rucifa iT邦新手 5 級 ‧ 2022-05-05 10:24:36 檢舉

謝謝前輩提醒

我要發表回答

立即登入回答