将大型 .tiff 文件导入为稀疏矩阵
Import large .tiff file as sparse matrix
我有一个带有 1 个波段的大型 .tiff 文件(4.4gB,79530 x 54980 值)。由于只有 16% 的值有效,我认为最好将文件导入为稀疏矩阵,以节省 RAM。当我第一次将它打开为 np.array
然后使用 csr_matrix()
将其转换为稀疏矩阵时,我的内核已经崩溃了。请参阅下面的代码。
from osgeo import gdal
import numpy as np
from scipy.sparse import csr_matrix
ds = gdal.Open("file.tif")
band = ds.GetRasterBand(1)
array = np.array(band.ReadAsArray())
csr_matrix(array)
有没有更好的方法来处理这个文件?最后,我必须根据栅格中的值进行计算。 (很遗憾,由于保密,我无法附上相关文件。)
假设您知道矩阵的大小,您可以创建一个空的稀疏矩阵,然后仅设置有效值 one-by-one。
from osgeo import gdal
import numpy as np
from scipy.sparse import csr_matrix
ds = gdal.Open("file.tif")
band = ds.GetRasterBand(1)
matrix_size = (1000, 1000) # set you size
matrix = csr_matrix(matrix_size)
# for each valid value
matrix[i, j] = your_value
编辑 1
如果您不知道矩阵的大小,您应该可以这样检查:
from osgeo import gdal
ds = gdal.Open("file.tif")
width = ds.GetRasterXSize()
height = ds.GetRasterYSize()
matrix_size = (width, height)
编辑 2
我测量了评论中建议的指标(已填满)。 This is how I measured memory usage.
尺寸 500x500
matrix
empty size
full size
filling time
csr_matrix
2856
2992
477.67 s
doc_matrix
726
35807578
3.15 s
lil_matrix
8840
8840
0.54 s
尺寸 1000x1000
matrix
empty size
full size
filling time
csr_matrix
4856
4992
7164.94 s
doc_matrix
726
150578858
12.81 s
lil_matrix
16840
16840
2.19 s
最好的解决方案可能是使用 lil_matrix
你能说出崩溃发生在哪里吗?
band = ds.GetRasterBand(1)
temp = band.ReadAsArray()
array = np.array(temp) # if temp is already an array, you don't need this
csr_matrix(array)
如果array
是4.4gB,(79530, 54980)
In [62]: (79530 * 54980) / 1e9
Out[62]: 4.3725594 # 4.4gB makes sense for 1 byte/element
In [63]: (79530 * 54980) * 0.16 # 16% density
Out[63]: 699609504.0 # number of nonzero values
创建 csr
需要执行 np.nonzero(array)
来获取索引。这将产生 2 个 0.7 * 8 Gb 大小的数组(索引是 8 字节整数)。 coo
格式实际上需要这 2 个数组加上非零值的 0.7 - 大约 12 Gb。转换为 csr
,row
属性减少到 79530 个元素 - 大约 7 Gb。 (更正为 8 bytes/element)
所以在 16% 的密度下,稀疏格式在最好的情况下仍然比密集版本大。
Memory error when converting matrix to sparse matrix, specified dtype is invalid
最近发生了内存错误 - 发生在 nonzero
步骤中。
我有一个带有 1 个波段的大型 .tiff 文件(4.4gB,79530 x 54980 值)。由于只有 16% 的值有效,我认为最好将文件导入为稀疏矩阵,以节省 RAM。当我第一次将它打开为 np.array
然后使用 csr_matrix()
将其转换为稀疏矩阵时,我的内核已经崩溃了。请参阅下面的代码。
from osgeo import gdal
import numpy as np
from scipy.sparse import csr_matrix
ds = gdal.Open("file.tif")
band = ds.GetRasterBand(1)
array = np.array(band.ReadAsArray())
csr_matrix(array)
有没有更好的方法来处理这个文件?最后,我必须根据栅格中的值进行计算。 (很遗憾,由于保密,我无法附上相关文件。)
假设您知道矩阵的大小,您可以创建一个空的稀疏矩阵,然后仅设置有效值 one-by-one。
from osgeo import gdal
import numpy as np
from scipy.sparse import csr_matrix
ds = gdal.Open("file.tif")
band = ds.GetRasterBand(1)
matrix_size = (1000, 1000) # set you size
matrix = csr_matrix(matrix_size)
# for each valid value
matrix[i, j] = your_value
编辑 1
如果您不知道矩阵的大小,您应该可以这样检查:
from osgeo import gdal
ds = gdal.Open("file.tif")
width = ds.GetRasterXSize()
height = ds.GetRasterYSize()
matrix_size = (width, height)
编辑 2
我测量了评论中建议的指标(已填满)。 This is how I measured memory usage.
尺寸 500x500
matrix | empty size | full size | filling time |
---|---|---|---|
csr_matrix | 2856 | 2992 | 477.67 s |
doc_matrix | 726 | 35807578 | 3.15 s |
lil_matrix | 8840 | 8840 | 0.54 s |
尺寸 1000x1000
matrix | empty size | full size | filling time |
---|---|---|---|
csr_matrix | 4856 | 4992 | 7164.94 s |
doc_matrix | 726 | 150578858 | 12.81 s |
lil_matrix | 16840 | 16840 | 2.19 s |
最好的解决方案可能是使用 lil_matrix
你能说出崩溃发生在哪里吗?
band = ds.GetRasterBand(1)
temp = band.ReadAsArray()
array = np.array(temp) # if temp is already an array, you don't need this
csr_matrix(array)
如果array
是4.4gB,(79530, 54980)
In [62]: (79530 * 54980) / 1e9
Out[62]: 4.3725594 # 4.4gB makes sense for 1 byte/element
In [63]: (79530 * 54980) * 0.16 # 16% density
Out[63]: 699609504.0 # number of nonzero values
创建 csr
需要执行 np.nonzero(array)
来获取索引。这将产生 2 个 0.7 * 8 Gb 大小的数组(索引是 8 字节整数)。 coo
格式实际上需要这 2 个数组加上非零值的 0.7 - 大约 12 Gb。转换为 csr
,row
属性减少到 79530 个元素 - 大约 7 Gb。 (更正为 8 bytes/element)
所以在 16% 的密度下,稀疏格式在最好的情况下仍然比密集版本大。
Memory error when converting matrix to sparse matrix, specified dtype is invalid
最近发生了内存错误 - 发生在 nonzero
步骤中。