Google Drive上のファイルをPythonで読み込む速度

IT・プログラミング

Google DriveのデータをPythonで読み込む方法については、以下の記事で紹介しました。

https:/lifetechia.com/google-drive-file/

今回は、ここで紹介したAPI取得と共有リンクを使った方法の実行速度を比較してみたいと思います。
API方式は一度ダウンロードして、読み込むので、共有リンクで直接読みにいくよりも実行時間がかかっているのではと思ったためです。

APIの場合

def authenticate_drive():
    creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=creds)
    return service

service = authenticate_drive()

def read_csv(file, folder_id, file_=None):
    if file_ is None:
        file_ = file
    if os.path.exists(file_)==False:
        download_file_from_drive(service, folder_id, file, file_)
    else:
        pass
    df = pd.read_csv(file_)
    return df

def file_list(folder_id):
    query = f"'{folder_id}' in parents and mimeType='text/csv'"

    # ファイルのIDと名前を取得
    results = service.files().list(
        q=query,
        spaces='drive',
        fields='files(id, name)'
    ).execute()

    files = results.get('files', [])
    return files

def download_file_from_drive(service, folder_id, file_name, local_file_path):
    # Google Driveから指定されたフォルダのCSVファイルをダウンロードする
    results = service.files().list(q=f"name='{file_name}' and '{folder_id}' in parents",
                                   spaces='drive',
                                   fields='files(id)').execute()
    file_id = results.get('files', [])[0].get('id')

    request = service.files().get_media(fileId=file_id)
    fh = io.FileIO(local_file_path, mode='wb')
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
def get_csv_data(folder_id, prefix=''):
    files = file_list(folder_id)
    df = pd.DataFrame()
    for file in files:
        file_name = file['name']
        if file_name.split('.')[1] == 'csv':
            add_df = read_csv(file_name, folder_id, file_=prefix+file_name)
            df = pd.concat([df, add_df])
    return df


import time

# 計測開始時間
start_time = time.time()

# 実行するコード
meta_df = get_csv_data(folder_id,prefix='meta_')
# 計測終了時間
end_time = time.time()

# 実行時間を計算
execution_time = end_time - start_time

print(f"実行時間: {execution_time:.4f} 秒")

10個ほどのCSVファイルの入ったフォルダに対して実行したところ約48秒でした。

共有リンクの場合

from google.oauth2 import service_account
from googleapiclient.discovery import build
SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = 'credentials.json' 
folder_id = ''
def authenticate_drive():
    creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=creds)
    return service

service = authenticate_drive()

def search_meta_file(service, folder_id):
    # クエリを作成して指定フォルダ内の.csvファイルを取得
    query = f"'{folder_id}' in parents and mimeType='text/csv'"

    # ファイルのIDと名前を取得
    results = service.files().list(
        q=query,
        spaces='drive',
        fields='files(id, name)'
    ).execute()

    files = results.get('files', [])

    return files

import time

# 計測開始時間
start_time = time.time()

# 実行するコード
files = search_meta_file(service, folder_id)

# ファイルリストをファイル名でソートする
sorted_files = sorted(files, key=lambda x: x['name'])

# ソートされたファイルリストからCSVファイルのIDを取得
meta_file_ids = [file['id'] for file in sorted_files if file['name'].split('.')[-1] == 'csv']
df = pd.DataFrame()
for file_id in meta_file_ids:
    add_data = pd.read_csv(f'https://drive.google.com/uc?export=download&id={file_id}')
    df = pd.concat([df,add_data])


# 計測終了時間
end_time = time.time()

# 実行時間を計算
execution_time = end_time - start_time

print(f"実行時間: {execution_time:.4f} 秒")

こちらの方法の場合は、約24秒と半分ほどでした。

ダウンロードしながら同時にデータフレームに読み込めればおそらく同じくらいの実行時間だと思うのですが、APIの場合、ダウンロードして、もう一度読み込んでいるので、やはり時間がかかっていそうでした。

コメント

タイトルとURLをコピーしました