While Josh’s answer here让我在如何将256x64x250值数组插入MysqL数据库方面取得了良好的开端.当我在我的数据上实际尝试他的INSERT语句时,结果非常慢(如16Mb文件的6分钟).
ny,nx,nz = np.shape(data) query = """INSERT INTO `data` (frame,sensor_row,sensor_col,value) VALUES (%s,%s,%s)""" for frames in range(nz): for rows in range(ny): for cols in range(nx): cursor.execute(query,(frames,rows,cols,data[rows,frames]))
我正在阅读MySQL for Python,它解释说这不是正确的方法,因为执行400万个单独的插入是非常低效的.
现在我的数据由很多零组成(实际超过90%),所以我抛出一个IF语句,所以我只插入大于零的值,而我使用executemany()代替:
query = """INSERT INTO `data` (frame,%s ) """ values = [] for frames in range(nz): for rows in range(ny): for cols in range(nx): if data[rows,frames] > 0.0: values.append((frames,frames])) cur.executemany(query,values)
这奇迹般地将我的处理时间缩短到大约20秒,其中14秒花费在创建值列表(37k行)和实际插入数据库4秒.
所以现在我想知道,我怎样才能进一步加快这个过程?因为我有一种感觉,我的循环非常低效,必须有更好的方法.如果我需要为每只狗插入30个测量值,这仍然需要10分钟,这对于这个数据量来说似乎太长了.
以下是我的原始文件的两个版本:with headers或without headers.我想尝试LOAD DATA INFILE,但我无法弄清楚如何正确解析数据.
解决方法
如果数据是一个numpy数组,你可以试试这个:
query = """INSERT INTO `data` (frame,%s ) """ values = [] rows,frames = numpy.nonzero(data) for row,col,frame in zip(rows,frames): values.append((frame,row,data[row,frame])) cur.executemany(query,values)
要么
query = """INSERT INTO `data` (frame,%s ) """ rows,frames = numpy.nonzero(data) values = [(row,frame,val) for row,val in zip(rows,frames,frames])] cur.executemany(query,values)
希望能帮助到你