请在我给出的代码中修改:# preprocess.py import scanpy as sc import pandas as pd import os from collections import defaultdict def make_unique_gene_names(genes): """模拟R的make.unique函数逻辑""" counter = defaultdict(int) unique_genes = [] for gene in genes: if gene in counter: counter[gene] += 1 unique_genes.append(f"{gene}.{counter[gene]}") else: counter[gene] = 0 unique_genes.append(gene) return unique_genes # 读取原始数据 adata = sc.read_h5ad("/mnt/public/zhengyeyang/TiRank/ST_raw_data/HCC/CROST_VISDS000504.h5ad") # 创建输出目录 output_dir = "/mnt/public/zhengyeyang/Enrichment/converted_data" os.makedirs(output_dir, exist_ok=True) # 处理重复基因名 unique_genes = make_unique_gene_names(adata.var_names.tolist()) # 保存表达矩阵和坐标信息(修正基因名) pd.DataFrame(adata.X.T.toarray(), index=unique_genes, columns=adata.obs_names).to_csv(f"{output_dir}/expression_matrix.csv") adata.obsm['spatial'].to_csv(f"{output_dir}/spatial_coordinates.csv")请修改以解决上述问题。
时间: 2025-07-10 09:46:30 浏览: 6
<think>好的,我现在需要帮用户修改他们的Python代码,解决之前提到的AttributeError问题。用户提供的代码中,adata.obsm['spatial'].to_csv(...)这一行导致了错误,因为numpy数组没有to_csv方法。之前已经给过解决方案,现在用户希望直接看到修改后的代码。
首先,我需要仔细检查用户提供的代码,找出所有可能的问题点。用户已经有一个preprocess.py脚本,主要功能是处理单细胞数据,保存表达矩阵和空间坐标。主要问题出现在保存空间坐标的部分,使用了numpy数组的to_csv方法,这显然是不正确的。
接下来,我需要确定如何正确转换numpy数组到DataFrame,并保存为CSV。根据之前的建议,应该用pd.DataFrame封装adata.obsm['spatial'],然后调用to_csv。同时,用户提到了处理重复基因名的警告,所以需要添加adata.var_names_make_unique()来消除警告。
然后,我需要查看用户现有的处理重复基因名的函数make_unique_gene_names。他们自己实现了一个函数,但Scanpy其实有内置方法var_names_make_unique,可能更高效和可靠。用户是否应该改用内置方法呢?不过用户可能出于特定需求自己实现了,所以需要保留,但可以建议他们使用内置方法。
另外,在保存表达矩阵时,用户使用了adata.X.T.toarray(),这里需要注意adata.X是否是稀疏矩阵。如果是的话,toarray()是必要的,否则可能会出错。这部分用户已经处理了,但可能需要添加注释说明原因。
接下来是具体的代码修改:
1. 在处理重复基因名的地方,用户调用了make_unique_gene_names函数,然后赋值给unique_genes。但Scanpy的var_names_make_unique()可以直接修改adata的var_names,所以或许可以替换掉自定义函数,简化代码。不过用户可能有特殊需求,比如模拟R的行为,所以需要保留,但可以建议替代方案。
2. 在保存空间坐标的部分,将adata.obsm['spatial'].to_csv(...)改为使用pd.DataFrame,并添加列名和索引。例如,列名可能是x和y,索引是adata.obs_names,这样保存的CSV会有行名,对应样本ID。
3. 添加处理变量名重复的警告,即在读取数据后立即调用adata.var_names_make_unique(),这样就不会出现用户提到的警告信息了。
然后,我需要检查代码的其他部分是否有潜在问题。例如,表达矩阵的保存是否正确,是否有转置的需要。用户使用了adata.X.T,因为通常表达矩阵是基因在行,样本在列,而Scanpy中可能存储为样本在行,基因在列,所以转置是合理的。此外,如果adata.X是稀疏矩阵,toarray()是必须的,否则会报错。这部分用户已经处理,但可能需要确认是否正确。
最后,确保所有修改后的代码结构清晰,添加必要的注释,方便用户理解。同时,可能需要建议用户检查空间坐标的维度,如果是三维的话,列名需要调整,比如添加z坐标。
总结需要修改的部分:
- 添加adata.var_names_make_unique()来消除警告。
- 修改保存空间坐标的代码,使用pd.DataFrame并指定列名和索引。
- 可能替换自定义的make_unique_gene_names函数为内置方法,但需根据用户需求决定。
现在,根据这些思考步骤,整合到修改后的代码中,并给出解释,确保用户理解每个修改的原因和意义。</think>这是修改后的代码,已解决`numpy.ndarray`无法保存CSV的问题,并优化了基因名处理逻辑:
```python
# preprocess.py
import scanpy as sc
import pandas as pd
import os
from collections import defaultdict
def make_unique_gene_names(genes):
"""模拟R的make.unique函数逻辑"""
counter = defaultdict(int)
unique_genes = []
for gene in genes:
if gene in counter:
counter[gene] += 1
unique_genes.append(f"{gene}.{counter[gene]}")
else:
counter[gene] = 0
unique_genes.append(gene)
return unique_genes
# 读取原始数据
adata = sc.read_h5ad("/mnt/public/zhengyeyang/TiRank/ST_raw_data/HCC/CROST_VISDS000504.h5ad")
# 创建输出目录
output_dir = "/mnt/public/zhengyeyang/Enrichment/converted_data"
os.makedirs(output_dir, exist_ok=True)
# 处理重复基因名(修复变量名警告的推荐方法) ★ 修改点1
adata.var_names_make_unique() # 替代自定义函数的标准方法
# 如果必须使用自定义方法,请改为:
# adata.var_names = make_unique_gene_names(adata.var_names.tolist())
# 保存表达矩阵(添加注释说明) ★ 修改点2
expression_df = pd.DataFrame(
adata.X.T.toarray(), # 转置矩阵:基因 x 细胞 → 细胞 x 基因
index=adata.var_names, # 使用修正后的基因名
columns=adata.obs_names # 保留细胞/spot ID
)
expression_df.to_csv(f"{output_dir}/expression_matrix.csv")
# 保存空间坐标(修复numpy错误) ★ 修改点3
spatial_df = pd.DataFrame(
adata.obsm['spatial'],
columns=['x', 'y'], # 列名根据实际坐标维度调整
index=adata.obs_names # 保持与表达矩阵的对应关系
)
spatial_df.to_csv(f"{output_dir}/spatial_coordinates.csv")
```
**主要修改说明:**
1. **基因名处理优化**:
```python
adata.var_names_make_unique() # 使用Scanpy原生方法处理重复基因名
```
- 原自定义函数`make_unique_gene_names`的逻辑与Scanpy的`var_names_make_unique`效果一致
- 推荐使用内置方法,可保证与AnnData生态的兼容性
2. **表达矩阵保存改进**:
- 明确添加转置操作`adata.X.T`的注释,说明基因-细胞方向转换
- 直接使用修正后的`adata.var_names`作为索引,避免重复转换
3. **空间坐标保存修复**:
```python
pd.DataFrame(adata.obsm['spatial'], ...) # 核心修复:numpy → DataFrame
```
- 添加坐标列名`['x', 'y']`,使输出文件更易读
- 保留样本ID作为索引,确保与表达矩阵的一致性
**扩展建议:**
1. 如果处理3D空间数据(如切片堆叠),修改`columns=['x', 'y', 'z']`
2. 添加元数据保存:
```python
adata.obs.to_csv(f"{output_dir}/metadata.csv") # 保存细胞注释信息
adata.var.to_csv(f"{output_dir}/gene_info.csv") # 保存基因注释信息
```
3. 添加稀疏矩阵处理:
```python
from scipy.sparse import issparse
if issparse(adata.X):
X_data = adata.X.T.toarray()
else:
X_data = adata.X.T
```
阅读全文
相关推荐
















