我有一个pandas数据框,它的索引指向一个numpy数组。对于这些索引,数组的值必须设置为1。我需要在一个巨大的核阵列上做数百万次。有没有比下面所示的方法更有效的方法?

from numpy import float32, uint
from numpy.random import choice
from pandas import DataFrame
from timeit import timeit

xy = 2000,300000
sz = 10000000
ind = DataFrame({"i":choice(range(xy[0]),sz),"j":choice(range(xy[1]),sz)}).drop_duplicates()
dtype = uint
repeats = 10

#original (~21s)
stmt = '''\
from numpy import zeros
a = zeros(xy, dtype=dtype)
a[ind.values[:,0],ind.values[:,1]] = 1'''

print(timeit(stmt, "from __main__ import xy,sz,ind,dtype", number=repeats))

#suggested by @piRSquared (~13s)
stmt = '''\
from numpy import ones
from scipy.sparse import coo_matrix
i,j = ind.i.values,ind.j.values
a = coo_matrix((ones(i.size, dtype=dtype), (i, j)), dtype=dtype).toarray()
'''

print(timeit(stmt, "from __main__ import xy,sz,ind,dtype", number=repeats))

我已经编辑了上面的文章,展示了@piRSquared建议的方法,并重新编写了它,以便进行苹果对苹果的比较。无论数据类型是什么(tried uint和float32),建议的方法都可以减少40%的时间。

最佳答案

操作时间

56.56 s

我只能稍微提高
i, j = ind.i.values, ind.j.values
a[i, j] = 1

新时间
52.19 s

但是,您可以使用scipy.sparse.coo_matrix实例化稀疏矩阵,然后将其转换为numpy.array,从而大大加快速度。
import timeit

stmt = '''\
import numpy, pandas
from scipy.sparse import coo_matrix

xy = 2000,300000

sz = 10000000
ind = pandas.DataFrame({"i":numpy.random.choice(range(xy[0]),sz),"j":numpy.random.choice(range(xy[1]),sz)}).drop_duplicates()

################################################
i, j = ind.i.values, ind.j.values
dtype = numpy.uint8
a = coo_matrix((numpy.ones(i.size, dtype=dtype), (i, j)), dtype=dtype).toarray()'''

timeit.timeit(stmt, number=10)

33.06471237000369

关于python - 使用 Pandas 数据框在numpy数组中设置索引,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45930691/

10-12 16:53
查看更多