iT邦幫忙

1

Python 批量讀取excel資料並寫入txt檔

  • 分享至 

  • xImage

簡單來說就是,我有一個excel檔案要轉成txt檔。
其中每一個欄位都有限定說要多少個位數(我用zfill函式來做)。

只是我現在卡住的地方是,當我的資料達到一定的數量後,
輸出到txt檔裡的資料就會減少一大半。

有查過一些資料說,資料可能都在緩衝區裡面,沒有傳完程式就關閉了。
為此,有試過用flush(),但是沒用。

所以想請教一下,這個問題有甚麼好一點的解決方式嗎?

看更多先前的討論...收起先前的討論...
alien663 iT邦研究生 3 級 ‧ 2023-01-17 11:18:51 檢舉
還是有些東西沒有掌握清楚,例如你的excel和記憶體各有多少?
Buffer的空間是有限的,如果單純Buffer不夠大,印象中是可以直接提升Buffer的空間。
但也有可能只是資料量太大,所以沒辦法一口氣把資料都讀進來(記憶體空間不構),試試看一次讀1000筆資料,然後多次處理?
ankle7766 iT邦新手 5 級 ‧ 2023-01-17 14:36:50 檢舉
有什麼樣的辦法去做多次處裡?
froce iT邦大師 1 級 ‧ 2023-01-17 14:50:00 檢舉
你不說你用的code沒辦法給什麼實際建議
ankle7766 iT邦新手 5 級 ‧ 2023-01-17 15:03:01 檢舉
import pandas as pd


df = pd.read_excel('test.xlsx', sheet_name = '工作表1', dtype=str)
nmp = df.values
print(len(nmp))
print(len(nmp[0]))
for j in range(len(nmp)):
for i in range(len(nmp[0])):
if i == 0:
nmp[j,i] = nmp[j,i].zfill(2)
elif i == 1:
nmp[j,i] = nmp[j,i].zfill(8)
elif i == 2:
nmp[j,i] = nmp[j,i].zfill(10)
elif i == 3:
nmp[j,i] = nmp[j,i].zfill(3)
elif i == 4:
nmp[j,i] = nmp[j,i].zfill(1)
elif i == 5:
nmp[j,i] = nmp[j,i].zfill(10)
elif i == 6:
nmp[j,i] = nmp[j,i].zfill(8)
elif i == 7:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 8:
nmp[j,i] = nmp[j,i].zfill(8)
elif i == 9:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 10:
nmp[j,i] = nmp[j,i].zfill(8)
elif i == 11:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 12:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 13:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 14:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 15:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 16:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 17:
nmp[j,i] = nmp[j,i].zfill(10)
elif i == 18:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 19:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 20:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 21:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 22:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 23:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 24:
nmp[j,i] = nmp[j,i].zfill(9)
elif i == 25:
nmp[j,i] = nmp[j,i].zfill(9)
content = str(nmp)
new_string = ''.join(char for char in content if char.isalnum())
print(len(new_string))

with open('file5.txt','w') as file:
for i in range(len(new_string)):
if i != 0 and i % 212 == 0:
file.write("\n" + new_string[i])


else:
file.write(new_string[i])
ankle7766 iT邦新手 5 級 ‧ 2023-01-17 15:03:41 檢舉
下面的迴圈是我希望每212個字元就做一次換行
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2
alien663
iT邦研究生 3 級 ‧ 2023-01-17 17:03:51

先說聲抱歉,跟題目無關,但是看到雙層迴圈的i、j放那樣,還有一堆if else,我忍不住改程式碼了。

import pandas as pd
df = pd.read_excel('test.xlsx', sheet_name = '工作表1', dtype=str)
nmp = df.values
print(len(nmp))
print(len(nmp[0]))

zfill_format = [2, 8, 10, 3, 1, 10, 8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9, 9, 9, 9, 9]

for i in range(len(nmp)):
    for j in range(len(nmp[0])):
        nmp[i, j] = nmp[i, j].zfill(zfill_format[j])
        
content = str(nmp)
new_string = ''.join(char for char in content if char.isalnum())
print(len(new_string))

with open('file5.txt','w') as file:
    for i in range(len(new_string)):
        if i != 0 and i % 212 == 0:
            file.write("\n" + new_string[i])
        else:
            file.write(new_string[i])

回歸正題,你的程式碼裡面有一堆危險的狀況,如果excel真的像你講的資料量龐大,那像下面這樣的操作其實會讓整體的資源消耗巨大,如果說會出問題我真的不是很意外....

new_string = ''.join(char for char in content if char.isalnum())

如果想知道怎樣批次取資料,我有查到pandas的用法,但我猜應該跟你的問題沒關係。

df = pd.read_excel("歷年國內主要觀光遊憩據點遊客人數月別統計.xlsx", sheet_name="2019", nrows=21)

整體分析程式碼,我會建議你不要對dataframe的資料作異動,建議把你要的輸出改到write資料之前,開啟file之後,用for loop一筆一筆資料調整成你要的格式輸出,再append到file後面。

關於excel撈資料的程式,我自己都是用以前寫的library,這邊提供給你參考 : Lib-Python

ankle7766 iT邦新手 5 級 ‧ 2023-01-17 21:27:45 檢舉

感謝建議
我要先消化一下

0
froce
iT邦大師 1 級 ‧ 2023-01-17 21:47:12

用 pandas 就要用徹底啊...拿大砲打小鳥幹嘛。

  1. 你用 str(nmp) 只會轉換出部分的資料,因為pandas如果print太多會截掉資料輸出,另外會跑出 column name之類額外訊息。
  2. 你幹嘛要212個字元換行?每列資料換行才對吧?
  3. 讀取大檔案建議engine用 openpyxl ,請用pip安裝

下面用6萬多筆資料的excel測過

import pandas as pd

zfill_format = [2, 8, 10, 3, 1, 10, 8, 9, 8, 9,
                8, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9, 9, 9, 9, 9]

excel = pd.read_excel("test.xlsx", sheet_name="工作表1",
                      engine='openpyxl', dtype='str')

for index, item in enumerate(zfill_format):
    excel.iloc[:, index] = excel.iloc[:, index].apply(lambda x: x.zfill(item))

content = "".join(d for d in excel.values.reshape(-1) if d.isalnum())

# 212個字換行
with open('demo.txt', "w") as f:
    for i in range(0, len(content), 212):
        f.write(content[i: i+212] + "\n")
ankle7766 iT邦新手 5 級 ‧ 2023-01-19 09:15:30 檢舉

感謝建議!!!!!!

我要發表回答

立即登入回答