如何从 python 中的字符索引中找到行号?

How to find the row number from a character index in python?

我有一个遗传数据集,其中一行的索引是基因的名称。我还希望找到任何给定基因的行号,这样我就可以在基因通过机器学习模型预测后单独查看基因 - 以解释基因在 shap 中的预测。我如何为 shap 图编码目前需要一个行号来提取特定基因。

我的数据是这样的:

Index   Feature1  Feature2   ... FeatureN
Gene1     1           0.2          10
Gene2     1           0.1          7
Gene3     0           0.3          10

例如,如果我想提取并查看 Gene3 的模型预测,我会这样做:

import shap
shap.initjs()

xgbr = xgboost.XGBRegressor()

def shap_plot(j):
    explainerModel = shap.TreeExplainer(xgbr)
    shap_values_Model = explainerModel.shap_values(X_train)
    p = shap.force_plot(explainerModel.expected_value, shap_values_Model[j], X_train.iloc[[j]],feature_names=df.columns)
    return(p)

shap_plot(3)

shap_plot(3) 对我来说是个问题,因为我实际上不知道我想要的基因是否在打乱的训练或测试数据的第 3 行。

有没有办法从已知的基因索引中提取行号?或者可能重新编码我的 shap plot 以便它接受我的字符串索引?我有生物学背景,所以任何指导将不胜感激。

尝试以下操作。 df 是您的数据框,结果将为您提供给定基因的行号(第一行将产生 1,等等)

list(df.index).index('Gene3')+1

#result

3

有很多方法可以获取与索引值或列值关联的行号。

例如,如果您的基因实际上位于名为 "Index" 的列中,您可以这样做:

x_train[x_train["Index"] == "gene3"].index + 1

如果没有,您可以随时通过在数据帧上调用 reset_index() 来实现。

另一种选择是在您的数据框中创建一个新列,例如从 1 到 n

mapping = x_train.assign(index_number=range(x_train.shape[0]))["index_number"]

现在 mapping 应该是这样的:

Index   index_mapping 
Gene1     0           
Gene2     1           
Gene3     2           

并调用 mapping["Gene2"] 应该 return 1.

除此之外,我注意到您正在使用力图。我建议您阅读 this article 为什么 shap 用决策图代替它们。

还有,你每次叫你的时候都在重建树解释器function.This效率很低,不如一次构建,然后多次查询:

class ShapPlotter:
    def __init__(self, model, x_train):
        self.explainer_model = shap.TreeExplainer(model)
        self.shap_values_Model = self.explainer_model.shap_values(x_train)
        self.gene_index_mapping = x_train.assign(index_value=range(x_train.shape[0]))["index_value"]

    def plot(gene):
        idx = self._get_index(gene)
        shap_plot = shap.force_plot(...) # replace j with idx here
        return shap_plot

    def _get_index(gene: str) -> int:
        # your choice of method here. e.g. 
        # in this case, I built a mapping series in the __init__ fn so you can get the index number by just indexing directly with the gene string: 
        return self.gene_index_mapping.loc[gene]
list(df[df.Index=='Gene3'].index)