Google DriveのデータをPythonで読み込む方法については、以下の記事で紹介しました。
今回は、ここで紹介した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の場合、ダウンロードして、もう一度読み込んでいるので、やはり時間がかかっていそうでした。