我的目标和问题的描述:
我目前正在使用 python(版本 3.6.12)中的scanpy和annadata包。如果你不熟悉这些包,只知道在属性中anndata.AnnData
存储了一个数据矩阵(numpy.ndarray
)X
。的列在属性中X
描述,行在属性中描述。有关更多信息,请参阅此链接panda.DataFrame
var
obs
我的目标是拥有一个从该类继承的类(例如 A 类)anndata.AnnData
。在这个子类中,我想实现一些处理方法来过滤掉某些行或列。更重要的是,我还希望这些方法以“就地”方式修改属性,而不需要返回副本(即没有return self
)。但是,当我删除return self
方法中的 时,不会修改类的实例。更准确地说,在self
函数内部修改了,但类的实例保持不变。
代码示例:
想象以下示例,其中 A 类继承自anndata.AnnData
. 类 A 有一个称为remove_last_row()
删除类 A 实例的最后一行(即 obs)的方法。
import anndata
import numpy as np
class A(anndata.AnnData):
def __init__(self, adata, data_type=None):
"""
Initition method
Parameters:
-----------
adata: anndata.AnnData,
The Anndata object
"""
super().__init__(adata)
def remove_last_row(self):
"""
Remove the last row of the anndata object
"""
print("--> In A.remove_last_row() method:")
print("before filtering: number rows = ", self.X.shape[0])
# get the row index to keep (i.e. the index of the obs without the last one)
index_to_keep = self.obs[:-1].values.astype(int)
# Keep only those index:
self = self[index_to_keep, :]
print("after filtering: number rows = ", self.X.shape[0])
print("<-- exit A.remove_last_row() method.")
使用该remove_last_row()
方法时的问题是实例(self)的行在函数内部被删除但它没有修改类的实例。请参见下面的示例:
# Create an AnnData object:
adata = anndata.AnnData(np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]))
# Create object A that is inherited from AnnData
obj_A = A(adata = adata)
# Test remove_last_row method
obj_A.remove_last_row()
print()
print("obj_A.X attribute = \n", obj_A.X)
结果是:
--> 在 A.remove_last_row() 方法中:
过滤前:number rows = 3
过滤后:number rows = 2
<-- 退出 A.remove_last_row() 方法。obj_A.X 属性 =
[[0. 0. 0.]
[1. 1. 1.]
[2. 2. 2.]]
我们看到在remove_last_row()
方法中,最后一行self
在函数内部被删除。但是,obj_A
(A 类的实例)没有被此方法修改。如何在不添加return self
.
附加信息:
- Python版本=3.6.12
- numpy 版本=1.19.1
- 数据版本=0.7.4
- 扫描版本=1.6.0
我还测试了一个我调用的方法,addition()
它为数组的每个元素添加了一个特定的值X
。使用这种方法,我不会遇到这个问题。
如果方法addition()
在 A 类中:
def addition(self, x=1):
"""
Add a value of x for each element in the X numpy array in the AnnData object
Parameters:
-----------
x: float,
The value added to every element
"""
self.X += x
我们可以测试:
# Create an AnnData object:
adata = anndata.AnnData(np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]))
# Create object A that is inherited from AnnData
print("Before addition")
obj_A = A(adata = adata)
print("obj_A.X attribute = \n", obj_A.X)
# Test the addition method
print()
obj_A.addition(x=1)
print()
print("After addition")
print("obj_A.X attribute = \n", obj_A.X)
结果是:
添加之前
obj_A.X 属性 =
[[0. 0. 0.]
[1. 1. 1.]
[2. 2. 2.]]添加
obj_A.X 属性后 =
[[1. 1. 1.]
[2. 2. 2.]
[3. 3. 3.]]
如您所见,该addition()
方法有效。它能够修改类的实例。