pandas在尝试读取bigquery时陷入困境

pandas在尝试读取bigquery时陷入困境,pandas,google-bigquery,Pandas,Google Bigquery,我在大查询中有一个相当大的表(大约9M行),我想通过pandas读取它 我尝试了阅读和使用[pd.read\u gbq()][1]函数,该函数在小表上运行良好 在大表上,它会在大约50秒后卡住(日志显示,已过..50秒)-没有给出错误或任何信息 我的问题是如何使用pd(块?)读取该表。任何关于放大这些bigquery读取的约定都会有所帮助 编辑/解析 除了Khan的答案,我最终实现了块,每次向一个文件写入500000个,然后将这些文件读取到dataframe,如下所示: def download

我在大查询中有一个相当大的表(大约9M行),我想通过pandas读取它

我尝试了阅读和使用
[pd.read\u gbq()][1]
函数,该函数在小表上运行良好

在大表上,它会在大约50秒后卡住(日志显示,
已过..50秒
)-没有给出错误或任何信息

我的问题是如何使用pd(块?)读取该表。任何关于放大这些bigquery读取的约定都会有所帮助

编辑/解析

除了Khan的答案,我最终实现了块,每次向一个文件写入500000个,然后将这些文件读取到dataframe,如下所示:

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))
def下载\u gbq_表(self):
如果不存在os.path.exists(self.tmp_dir):
os.makedirs(self.tmp_dir)
增量=100000
间隔=列表(范围(0,self.table_size,100000))
interval.append(self.table_size-interval[len(interval)-1])
df=pd.DataFrame()
对于间隔偏移:
query=f“从``limit{increment}offset{offset}中选择*
info(f“运行查询:{query}”)
开始时间=time.time()
tmp_df=pd.read_gbq(查询,
project\u id=self.connection\u参数['project\u id'],
private_key=self.connection_参数['service_account'],
方言标准
)
df=pd.concat([df,tmp_-df])
info(f'time take:{str(round(time.time()-start\u time,2))})
如果len(df)%500000==0:
to_csv(os.path.join(self.tmp_dir,f'df_{str(offset+increment)}.csv'))
df=pd.DataFrame()
从多个csv(自身)读取def df:
all_files=glob.glob(os.path.join(self.tmp_dir,“df_*”))
df_列表=[]
对于所有_文件中的f:
开始时间=time.time()
df_list.append(pd.read_csv(f))
info(f'读取{f}:{str(round(time.time()-start_time,2))}'所用的时间)
返回pd.concat((所有_文件中f的pd.read_csv(f))

Pandas'
read\u gbq
函数当前未提供
chunksize
参数(即使其与
函数相反的
提供了
chunksize
参数)

无论如何,您可以通过向SQL查询添加
LIMIT
OFFSET
来解决问题,从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..

为什么这一行用于:
chunks[-1]+=increment
?只是为了确保范围包括所有内容(并且不会因为步长而后退)。如果这对您有帮助,请将答案标记为正确。谢谢:)