# Creating and connecting
##Creating Loom files
创建一个loom文件,需要提供一个矩阵数据(numpy ndarray or scipy sparse matrix)和两个关于行列属性的字典(字典中,属性名是键值,numpy ndarrays是对应的值)。如果矩阵数据是N×M,行属性必需有N个元素,列属性应该有M个元素。
例,创建一个有100x100维矩阵数据以及一个行属性,一个列属性的loom文件:
import numpy as np
import loompy
filename = "test.loom"
matrix = np.arange(10000).reshape(100,100)
row_attrs = { "SomeRowAttr": np.arange(100) }
col_attrs = { "SomeColAttr": np.arange(100) }
loompy.create(filename, matrix, row_attrs, col_attrs)
-
loompy.create()
接受numpy dense matrices (numpy.ndarray
) ,scipy sparse matrices(scipy.sparse.coo_matrix
,scipy.sparse.csc_matrix
, orscipy.sparse.csr_matrix
)
import numpy as np
import loompy
import scipy.sparse as sparse
filename = "test.loom"
matrix = sparse.coo_matrix((100, 100))
row_attrs = { "SomeRowAttr": np.arange(100) }
col_attrs = { "SomeColAttr": np.arange(100) }
loompy.create(filename, matrix, row_attrs, col_attrs)
#loompy.create()
只是创建文件文件
#loompy.connect()
可以连接loom文件,进行处理
-
loompy.new()
可以创建一个空的loom文件,并且返回与loom文件之间的链接,然后就可以向文件中填充数据。
for sample in samples:
with loompy.connect(sample) as dsin:
logging.info(f"Appending {sample}.")
dsout.add_columns(ds.layers, col_attrs=dsin.col_attrs, row_attrs=dsin.row_attrs)
-
loompy.combine()
根据一个已经存在的loom文件创建新的loom文件。新的内容写进去之后会根据列的维度进行填充,所以新内容和源文件内容应该有一样行数;如果对应的行的顺序不一致,可以通过添加参数Key
进行调整。
loompy.combine(files, output_filename, key="Accession")
- loompy.create_from_cellranger()导入10X Genomics cellranger结果
loompy.create_from_cellranger(folder, output_filename)
##Connecting to Loom files
#loompy.connect()
可以创建loom文件的链接,不会直接读入文件;因此,就算文件特别大也不影响其速度。
- 可以使用一个with语句来处理连接:
with loompy.connect("filename.loom") as ds:
# do something with ds
#with会自动关闭文件,不使用with的时候,你需要自行关闭
ds = loompy.connect("filename.loom")
ds.close()
#Manipulate data
##Shape, indexing and slicing
-
LoomConnection.shape
返回包含行列数的一个元组
>>> ds.shape
(100, 2345)
#loom matrix中数据可以通过索引和切片进行获取。
- Indices: anything that can be converted to a Python long
- Slices (i.e.
:
or0:10
) - Lists of the rows/columns you want (i.e.
[0, 34, 576]
) - Mask arrays (i.e. numpy array of bool indicating the rows/columns you want)
ds[0:10, 0:10] # Return the 10x10 submatrix starting at row and column zero
ds[99, :] # Return the 100th row
ds[:, 99] # Return the 100th column
ds[[0,3,5], :] # Return rows with index 0, 3 and 5
ds[:, bool_array] # Return columns where bool_array elements are True
#提示:一次选取太多的行或者列,速度会很慢,这是由于h5py造成的。当然,如果你把整个文件读入到内存中,不存在这个问题。还有一种选择,可以使用LoomConnection.scan(),当随机选取的列或者行超过数据1%时,它会很快。
## ##Sparse data
不同层的数据都是以块的方式存放,有助于数据储存和读取;不同层的数据都可以赋于新的稠密或者稀疏矩阵数据,
- 可以导入主矩阵或者任意层的数据,返回稀疏矩阵
ds.layers["exons"].sparse() # Returns a scipy.sparse.coo_matrix
ds.layers["unspliced"].sparse(rows, cols) # Returns only the indicated rows and columns (ndarrays of integers or bools)
- 给层非陪数据
ds.layers["exons"] = my_sparse_matrix
## ##Modifying layers
修改不同层的数据,直接索引数重新进行赋值就可以了。
ds[:, :] = newdata # Assign a full matrix
ds[3, 500] = 31 # Set the element at (3, 500) to the value 31
ds[99, :] = rowdata # Assign new values to row with index 99
ds[:, 99] = coldata # Assign new values to column with index 99
## ##Global attributes
全局属性使用.attrs.访问,通过赋值创建新的属性,del可以删除属性
>>> ds.attrs.title
"The title of the dataset"
>>> ds.attrs.title = "New title"
>>> ds.attrs["title"]
"New title"
>>> del ds.attrs.title
loom的属性可以像字典一样遍历处理
>>> ds.attrs.keys()
["title", "description"]
>>> for key, value in ds.attrs.items():
>>> print(f"{key} = {value}")
title = New title
description = Fancy dataset
#全局属性可以是标量或任意形状的多维数组,元素可以是整数、浮点数或字符串。
##Row and column attributes
- 行和列属性是分别通过
ds.ra
,ds.ca
访问的。
ds.ca.keys() # Return list of column attribute names
ds.ra.Gene = ... # Create or replace the Gene attribute
a = ds.ra.Gene # Assign the array of gene names (assuming the attribute exists)
del ds.ra.Gene # Delete the Gene row attribute
- 属性也可以通过索引来访问:
a = ds.ra["Gene"] # Assign the array of gene names (assuming the attribute exists)
del ds.ra["Gene"] # Delete the Gene row attribute
- 你可以将多个具有相同类型的属性提取到一个numpy数组中
a = ds.ra["Gene", "Attribute"] # Returns a 2D array of shape (n_genes, 2)
b = ds.ca["PCA1", "PCA2"] # Returns a 2D array of shape (n_cells, 2)
- 访问多个属性
a = ds.ra["Gene", "GeneName"] # Return one or the other (if only one exists)
b = ds.ca["TSNE", "PCA", "UMAP"] # Return the one that exists (if only one exists)
- 使用属性来模糊索引主矩阵,在选择子数组时可以使用非常紧凑和可读的语法:
array([[ 2., 9., 9., ..., 0., 14., 0.]], dtype=float32)
>>> ds[(ds.ra.Gene == "Actb") | (ds.ra.Gene == "Gapdh"), :]
array([[ 2., 9., 9., ..., 0., 14., 0.],
[ 0., 1., 4., ..., 0., 14., 3.]], dtype=float32)
>>> ds[:, ds.ca.CellID == "AAACATACATTCTC-1"]
array([[ 0.],
[ 0.],
[ 0.],
...,
[ 0.],
[ 0.],
[ 0.]], dtype=float32)
#可以使用位运算符,|
for ‘or’, &
for ‘and’ and ~
for ‘not’。
(a == b) & (a > c) | ~(c <= b)
##Modifying attributes
与层不同,属性总是只能完整地读写。因此,给切片赋值不会修改磁盘上储存的属性内容。要为一个属性赋予新值,必须为该属性赋值一个完整的列表或ndarray:
with loompy.connect("filename.loom") as ds:
ds.ca.ClusterNames = values # where values is a list or ndarray with one element per column
# This does not change the attribute on disk:
ds.ca.ClusterNames[10] = "banana"
##Adding columns
- 您可以向现有的loom文件添加列。添加行或删除矩阵的任何部分无法操作。
ds.add_columns(submatrix, col_attrs)
- 如果要向空文件添加列,还必须提供行属性:
ds.add_columns(submatrix, col_attrs, row_attrs={"Gene": genes})
- 你也可以添加另一个.loom文件的内容:other_file添加到ds中
ds.add_loom(other_file, key="Gene")
#注:other_file和ds应该有一样的行数,在列的维度进行合并,如果行的顺序不一致,可以通过参数key进行重排,缺失值可以自动通过fill_values填充。如果文件包含任何具有冲突值的全局属性,则可以通过将convert_attrs=True传递给该方法来自动将这些属性转换为列属性。
##Layers
loom支持多层, 每个loom只有一个的主矩阵,但可以有一个或多个具有相同行数和列数的额外层。使用LoomConnection对象上的Layers属性访问层。
- 层支持与属性相同的python API:
ds.layers.keys() # Return list of layers
ds.layers["unspliced"] # Return the layer named "unspliced"
ds.layers["spliced"] = ... # Create or replace the "spliced" layer
a = ds.layers["spliced"][:, 10] # Assign the 10th column of layer "spliced" to the variable a
del ds.layers["spliced"] # Delete the "spliced" layer
#主矩阵也可以通过“”进行访问(类似使用层名);但是不能删除主矩阵,其它层的方法也适用于主矩阵。
- 为了方便起见,层也可以直接在连接对象上使用。
ds["spliced"] = ... # Create or replace the "spliced" layer
a = ds["spliced"][:, 10] # Assign the 10th column of layer "spliced" to the variable a
del ds["spliced"] # Delete the "spliced" layer
- 有时您可能需要创建一个空层(全部为零),以便稍后填充。空层是通过为层名指定类型来创建的。例如:
ds["empty_floats"] = "float32"
ds["empty_ints"] = "int64"
##Graphs
Loom支持以行或列作为节点的稀疏图。例如,细胞的稀疏图(存储在列中)可以表示细胞的KNN图。在这种情况下,细胞就是节点(如果主矩阵中有M列,则图中有M个节点),它们由任意数量的边连接。图可以被认为是有向的或无向的,并且可以在边缘上有浮点值的权值。Loom甚至支持多图(允许节点对之间有多条边)。图存储为边和相关边权值的数组。
- 行图和列图在使用ds.row_graphs 和 ds.col_graphs访问。例如:
ds.row_graphs.keys() # Return list of row graphs
ds.col_graphs.KNN = ... # Create or replace the column-oriented graph KNN
a = ds.col_graphs.KNN # Assign the KNN column graph to variable a
del ds.col_graphs.KNN # Delete the KNN graph
##Views
loompy Views的功能是通过切片将loom文件特定的内容读入到内存,然后进行查看。
ds.view[:, 10:20]
##Operations
###Map
- 通过map方法可以在数据行或者列的维度上对数据进行迭代处理:
ds.map([np.mean, np.std], axis=1)
map()结合scan()可以遍历处理整个文件内容。
- map对于函数设置的参数接受一个函数list,然后将每个函数都在整个数据进行遍历,就算一个函数也应该是list结构。
(means,) = ds.map([np.mean], axis=1)
###Permutation
- 排列行或列的顺序:
rdering = np.random.permutation(np.arange(ds.shape[1]))
ds.permute(ordering, axis=1)
#排列文件中的行或列的顺序,是不需要将整个文件加载到RAM中。
###Scan
- 对于非常大的织机文件,分批(batches)scan文件(沿着行或列)是非常有用的,以避免将整个文件加载到内存中。这可以使用scan()方法实现:
for (ix, selection, view) in ds.scan(axis=1):
# do something with each view
#axis=0表示行,axis=1表示列;
#ix是提取内容的索引起始位置
#selection是提取的内容列的list
#view是一个loom对象;loom的一些方法都可以进行运用。
import numpy as np
import loompy
filename = "test.loom"
matrix = np.arange(10000).reshape(100,100)
row_attrs = { "SomeRowAttr": np.arange(100) }
col_attrs = { "SomeColAttr": np.arange(100) }
loompy.create(filename, matrix, row_attrs, col_attrs)
ds = loompy.connect("test.loom")
for (ix, selection, view) in ds.scan(axis=1):
print(ix, selection)
0 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
96 97 98 99]
- 还可以选定的列或行子集内容进行扫描。例如:
cells = # List of columns you want to see
for (ix, selection, view) in ds.scan(items=cells, axis=1):
# do something with each view
#cell就是对应的index; array([ 0, 1, 2, 3])
loom R版本参考: loomR介绍及使用指南
网友评论