Панды застревает при попытке прочитать из BigQuery - PullRequest
0 голосов
/ 13 февраля 2019

У меня довольно большая таблица в большом запросе (около 9M строк), и я хотел бы прочитать ее через панд.

Я пробовал читать и использовать функцию [pd.read_gbq()][1], которая отлично работает на небольших столах.

На большом столе он застревает примерно через 50 секунд (журналы показывают elapsed .. 50s) - без ошибок или чего-либо еще.

Мой вопрос: как мне прочитать эту таблицу, используя pd (chunks?).Любые соглашения по расширению этих больших запросов будут полезны.

РЕДАКТИРОВАТЬ / разрешение

добавив к ответу Хана, я закончил тем, что реализовал куски, записывая 500 000 каждый раз вфайл, а затем читать эти файлы в фрейм данных так:

def download_gbq_table(self):
    if not os.path.exists(self.tmp_dir):
        os.makedirs(self.tmp_dir)
    increment = 100000

    intervals = list(range(0, self.table_size, 100000))
    intervals.append(self.table_size - intervals[len(intervals)-1])

    df = pd.DataFrame()

    for offset in intervals:
        query = f"select * from `<table_name>` limit {increment} offset {offset};"
        logger.info(f"running query: {query}")
        start_time = time.time()
        tmp_df = pd.read_gbq(query,
                       project_id=self.connection_parameters['project_id'],
                       private_key=self.connection_parameters['service_account'],
                       dialect='standard'
                        )
        df = pd.concat([df, tmp_df])
        logger.info(f'time took: {str(round(time.time() - start_time, 2))}')
        if len(df) % 500000 == 0:
            df.to_csv(os.path.join(self.tmp_dir, f'df_{str(offset + increment)}.csv'))
            df = pd.DataFrame()

def read_df_from_multi_csv(self):
    all_files = glob.glob(os.path.join(self.tmp_dir, "df_*"))
    df_list = []

    for f in all_files:
        start_time = time.time()
        df_list.append(pd.read_csv(f))
        logger.info(f'time took for reading {f}: {str(round(time.time() - start_time, 2))}')

    return pd.concat((pd.read_csv(f) for f in all_files))

1 Ответ

0 голосов
/ 13 февраля 2019
Функция

Pandas read_gbq в настоящее время не обеспечивает параметр chunksize (хотя ее противоположная функция to_gbq предоставляет параметр chunksize).

В любом случае, вы можете решить свою проблему, добавив LIMIT и OFFSET к своему запросу SQL, итеративно читая материал из BigQuery.Что-то на линии:

project_id = "xxxxxxxx"

increment=100000
chunks=range(0, 9000000, 100000)

chunks[-1]+=increment 
intervals=[[chunks[i-1], chunks[i]+1] for i, e in enumerate(chunks) if i > 0]

query_str="select * from `mydataset.mytable` limit {end} offset {start};"

for start, end in intervals:
   query = query_str.format(start=start, end=end)
   df = pd.read_gbq(query, project_id)
   #-- do stuff with your df here..
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...