我有以下功能:
def json_to_pickle(json_path=REVIEWS_JSON_DIR,
pickle_path=REVIEWS_PICKLE_DIR,
force_update=False):
'''Create a pickled dataframe from selected JSON files.'''
current_date = datetime.today().strftime("%Y%m%d")
filename_safe_path = json_path.replace("/", "_")
# Get a list of all JSON files from a given directory
in_paths = Path(json_path).glob("**/*.json")
in_paths_list = []
for path in in_paths: # Convert generator to a simple list
in_paths_list.append(path)
out_path = (f"{pickle_path}"
f"/{current_date}"
f"_{filename_safe_path}"
f"_reviews.pkl")
if exists(out_path) == False or force_update == True:
pprint("Creating a new pickle file from raw JSON files")
df = pd.DataFrame()
for path in tqdm(in_paths_list):
with open(path, "r") as file:
normalized_json_df = pd.json_normalize(json.load(file))
df = pd.concat([df, normalized_json_df])
df.to_pickle(out_path, compression="infer")
else:
pprint(f"Using existing pickle file ({out_path})")
return out_path
除非 pickle 檔案已經存在,否則它會在給定目錄(包括所有子目錄)中查找所有 JSON 檔案,對其進行規范化,將它們連接到資料幀,并將資料幀作為 pickle 保存到磁盤。處理 240.255 個 JSON 檔案需要 54 分鐘。
根據tqdm,for-loop 平均每秒 73.51 次迭代(在具有 10 個內核的 M1 MacBook Pro 上運行),但隨著時間的推移它似乎變得更慢。據推測,隨著資料框變大。它從每秒大約 1668.44 次迭代開始。
所有 JSON 檔案都具有相同的結構,但可能缺少幾個欄位。大小在 500 位元組到 2 KB 之間變化。這是來自 Google 檔案的 JSON 規范。
我能做些什么來加快這個for回圈?
編輯:
這就是我for根據所選答案更改 -loop 的方式:
data_frames = []
for path in tqdm(in_paths_list):
with open(path, "r") as file:
data_frames.append(pd.json_normalize(json.load(file)))
pd.concat(data_frames).to_pickle(out_path, compression="infer")
現在它在 1 分 29 秒內完成。相當的進步!
uj5u.com熱心網友回復:
與其加載每個檔案并將其附加到更大的臨時資料框中,不如將所有檔案加載到資料框中并在一次操作中將它們連接起來。
當前代碼加載與檔案對應的 N個資料幀,并使用完全相同的資料創建 N-1 個更大的資料幀。
我使用此代碼將檔案夾中的所有 Excel 檔案加載到單個資料框中:
root = rf"C:\path\to\folder"
matches=Path(root).glob("22*.xls*")
files=tqdm((pd.read_excel(file,skipfooter=1)
for file in matches
if not file.name.startswith("~")))
df=pd.concat(files)
在問題的情況下,您可以使用:
def load_json(path):
with open(path, "r") as file:
df = pd.json_normalize(json.load(file))
return df
in_paths = Path(json_path).glob("**/*.json")
files=tqdm((load_json(file) for file in in_paths))
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/477560.html
上一篇:使用for回圈的函式回傳不同的值
