Python 从多个多维数组中合并和归一化数据的最快方法

Python 从多个多维数组中合并和归一化数据的最快方法,python,mysql,arrays,numpy,Python,Mysql,Arrays,Numpy,我有一组数据,它有三个维度X,Y,Z,顺序为24,67,95 和8个变量:a,b,c,d,e,f,g,h 每个变量存储在[X,Y,Z]numpy数组()中,即具有24*67*95=152760个值 数组组合成一个OrderedDict(),键是变量的名称 因此,维度x,y,z的变量a的值由数据['a'][x][y][z]给出 我想以标准化格式将此数据插入MySQL表中,该表由x、y、z索引: --------------------- |x|y|z|a|b|c|d|e|f|g|h| ----

我有一组数据,它有三个维度X,Y,Z,顺序为24,67,95 和8个变量:a,b,c,d,e,f,g,h

每个变量存储在[X,Y,Z]numpy数组()中,即具有24*67*95=152760个值

数组组合成一个OrderedDict(),键是变量的名称

因此,维度x,y,z的变量a的值由数据['a'][x][y][z]给出

我想以标准化格式将此数据插入MySQL表中,该表由x、y、z索引:

 ---------------------
|x|y|z|a|b|c|d|e|f|g|h|
 ---------------------
| | | | | | | | | | | |
我以以下方式执行此操作,在x的每一步生成一个67*95=6365条的insert语句,我知道这是MySQL的最佳数量级:

cur = db.cursor()
Xs = 24
Ys = 67
Zs = 95    
variables = ['a','b','c','d','e','f','g','h']
for x in range(Xs):
    sql="insert into mytable (X,Y,Z"
    for variable in variables:
        sql+=","+variable
    sql+=") values"
    for y in range(Ys):
        for z in range(Zs):
            sql+="(%d,%d,%d" % (x,y,z)
            for variable in variables:
                sql+=","+str(data[variable][x][y][z])
            sql+="),"
    cur.execute(sql[:-1])
在我的四核PC上,每次X迭代运行循环总时间约为24秒,执行insert语句只占用约0.5秒的时间

有没有更快的方法在内存中组合和规范化这些变量

(我知道标准化数据库可能不是此类多维数据的最佳存储格式,我随后将对此进行测试——就本问题而言,假设它是)


谢谢

看看这段代码,我认为有很多地方可以改进。以下是我的看法:

cur = db.cursor()
Xs = 24
Ys = 67
Zs = 95    
variables = ['a','b','c','d','e','f','g','h']
sql = ("INSERT INTO mytable (X, Y, Z, " +
       ', '.join(variables) +
       ') VALUES ({0})').format(','.join(['%s'] * (len(variables) + 3)))

for x in range(Xs):
    for y in range(Ys):
        values = []
        for z in range(Zs):
            values = [x, y, z]
            for variable in variables:
                values.append(data[variable][x][y][z])
            cur.execute(sql, values)
SQL语句只创建一次。这些值存储在一个列表中,该列表在传递到游标的
execute()
方法时传递

要进一步改进它,需要将所有值存储在一个列表中,并使用
executemany()


我无法测试上述内容,因为我没有测试数据,但我希望能够清楚地知道发生了什么变化。

使用生成的浮点值尝试了您的代码,并使用SQL命令生成了一个长字符串-在我的笔记本电脑上只花了不到2.5秒的时间。如果我没看错你的帖子,你有24*67*95*8个数字。还有一些事情似乎在消耗你的时间。两个小建议:(1)Numpy数组的索引为
array[x,y,z]
,但你使用了
array[x][y][z]
。(2) 将SQL命令的各个部分收集到一个列表中,并在最后执行
str.join
,以避免每次分配越来越长的字符串(在Python中不能真正附加到字符串,因为它们是不可变的)。也许更好的做法是,在数组上调用
tolist()
方法并为嵌套列表编制索引,因为它比索引numpy数组快。您尝试过numpy记录数组吗?这样你就有了一个4D numpy数组,在其中你也可以使用你的变量名。谢谢你——因为你的回答,我进一步研究了,而且我访问的数据集的结构似乎比我想象的更复杂,从而减慢了访问每个元素的操作。通过将数组从数据集中提取到处理前描述的形式中,现在每次迭代只需0.2秒,而无需更改任何其他内容。仍然不确定最初的数据结构为何如此缓慢,但至少它现在可以工作了!在我上面的评论中,似乎逐个元素访问原始数据结构的调用是缓慢的,通过将所有数据提取到一个新的字典中,这个过程已经加快了100多倍。但是,我也实现了您的解决方案,它再次将速度提高了一倍,因此我将此标记为所述问题的正确答案。谢谢
all_values = []
for x in range(Xs):
    for y in range(Ys):
        values = []
        for z in range(Zs):
            values = [x, y, z]
            for variable in variables:
                values.append(data[variable][x][y][z])
            all_values.append(values)

cur.executemany(sql, all_values)