Plotly堆叠条形图触发UFuncTypeError,求问题排查与解决方案
问题:基于疾病亚型创建特征频率堆叠条形图时触发UFuncTypeError
我希望基于admin.disease_code中的亚型,使用Plotly创建展示各特征频率的堆叠条形图,但运行代码时触发了UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U18'), dtype('int64')) -> None错误。
相关代码与报错信息
导入代码
import pandas as pd import numpy as np import plotly.express as px
分组聚合代码
agg_df = df.groupby(["admin.disease_code"]).agg({'count'}) agg_df = agg_df.drop("tcga_id", axis=1) agg_df.columns = agg_df.columns.get_level_values(0) agg_df.rename(columns = {'patient.days_to_death':'days_to_death', 'patient.vital_status':'vital_status', 'patient.age_at_initial_pathologic_diagnosis':'age_at_initial_pathologic_diagnosis', 'patient.gender':'gender','patient.karnofsky_performance_score':'karnofsky_performance_score'}, inplace = True)
绘图代码
fig = px.bar(agg_df, x=agg_df.columns, title="Clinical information for RCC subtypes") fig.show()
报错回溯
--------------------------------------------------------------------------- UFuncTypeError Traceback (most recent call last) /tmp/ipykernel_17/79231555.py in <module> ----> 1 fig = px.bar(agg_df, x=agg_df.columns, title="Clinical information for RCC subtypes") 2 fig.show() /opt/conda/lib/python3.7/site-packages/plotly/express/_chart_types.py in bar(data_frame, x, y, color, pattern_shape, facet_row, facet_col, facet_col_wrap, facet_row_spacing, facet_col_spacing, hover_name, hover_data, custom_data, text, base, error_x, error_x_minus, error_y, error_y_minus, animation_frame, animation_group, category_orders, labels, color_discrete_sequence, color_discrete_map, color_continuous_scale, pattern_shape_sequence, pattern_shape_map, range_color, color_continuous_midpoint, opacity, orientation, barmode, log_x, log_y, range_x, range_y, text_auto, title, template, width, height) 375 constructor=go.Bar, 376 trace_patch=dict(textposition="auto"), --> 377 layout_patch=dict(barmode=barmode), 378 ) 379 /opt/conda/lib/python3.7/site-packages/plotly/express/_core.py in make_figure(args, constructor, trace_patch, layout_patch) 1988 apply_default_cascade(args) 1989 -> 1990 args = build_dataframe(args, constructor) 1991 if constructor in [go.Treemap, go.Sunburst, go.Icicle] and args["path"] is not None: 1992 args = process_dataframe_hierarchy(args) /opt/conda/lib/python3.7/site-packages/plotly/express/_core.py in build_dataframe(args, constructor) 1457 value_vars=wide_value_vars, 1458 var_name=var_name, -> 1459 value_name=value_name, 1460 ) 1461 assert len(df_output.columns) == len(set(df_output.columns)), ( /opt/conda/lib/python3.7/site-packages/pandas/core/frame.py in melt(self, id_vars, value_vars, var_name, value_name, col_level, ignore_index) 8344 value_name=value_name, 8345 col_level=col_level, -> 8346 ignore_index=ignore_index, 8347 ) 8348 /opt/conda/lib/python3.7/site-packages/pandas/core/reshape/melt.py in melt(frame, id_vars, value_vars, var_name, value_name, col_level, ignore_index) 142 mdata[col] = id_data 143 -> 144 mcolumns = id_vars + var_name + [value_name] 145 146 # error: Incompatible types in assignment (expression has type "ndarray", UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U18'), dtype('int64')) -> None
数据信息
数据样例(df.head().to_dict())
{'admin.disease_code': {'TCGA-2K-A9WE-01A-11D-A381-01': 'kirp', 'TCGA-2Z-A9J1-01A-11D-A381-01': 'kirp', 'TCGA-2Z-A9J2-01A-11D-A381-01': 'kirp', 'TCGA-2Z-A9J3-01A-12D-A381-01': 'kirp', 'TCGA-2Z-A9J5-01A-21D-A381-01': 'kirp'}, 'patient.days_to_death': {'TCGA-2K-A9WE-01A-11D-A381-01': nan, 'TCGA-2Z-A9J1-01A-11D-A381-01': nan, 'TCGA-2Z-A9J2-01A-11D-A381-01': nan, 'TCGA-2Z-A9J3-01A-12D-A381-01': '1771', 'TCGA-2Z-A9J5-01A-21D-A381-01': nan}, 'patient.age_at_initial_pathologic_diagnosis': {'TCGA-2K-A9WE-01A-11D-A381-01': '53', 'TCGA-2Z-A9J1-01A-11D-A381-01': '71', 'TCGA-2Z-A9J2-01A-11D-A381-01': '71', 'TCGA-2Z-A9J3-01A-12D-A381-01': '67', 'TCGA-2Z-A9J5-01A-21D-A381-01': '80'}, 'patient.karnofsky_performance_score': {'TCGA-2K-A9WE-01A-11D-A381-01': nan, 'TCGA-2Z-A9J1-01A-11D-A381-01': nan, 'TCGA-2Z-A9J2-01A-11D-A381-01': nan, 'TCGA-2Z-A9J3-01A-12D-A381-01': nan, 'TCGA-2Z-A9J5-01A-21D-A381-01': nan}, 'tcga_id': {'TCGA-2K-A9WE-01A-11D-A381-01': 'TCGA-2K-A9WE-01A', 'TCGA-2Z-A9J1-01A-11D-A381-01': 'TCGA-2Z-A9J1-01A', 'TCGA-2Z-A9J2-01A-11D-A381-01': 'TCGA-2Z-A9J2-01A', 'TCGA-2Z-A9J3-01A-12D-A381-01': 'TCGA-2Z-A9J3-01A', 'TCGA-2Z-A9J5-01A-21D-A381-01': 'TCGA-2Z-A9J5-01A'}, 'survival': {'TCGA-2K-A9WE-01A-11D-A381-01': 'lts', 'TCGA-2Z-A9J1-01A-11D-A381-01': 'lts', 'TCGA-2Z-A9J2-01A-11D-A381-01': 'lts', 'TCGA-2Z-A9J3-01A-12D-A381-01': 'non-lts', 'TCGA-2Z-A9J5-01A-21D-A381-01': 'lts'}}
agg_df数据类型
0 patient.days_to_death int64 patient.age_at_initial_pathologic_diagnosis int64 patient.karnofsky_performance_score int64 survival int64 dtype: object
期望输出

解决方案
错误原因分析
- 参数与数据结构不匹配:
agg_df的索引是疾病亚型,列是各特征的非空计数,但px.bar错误地将列名设为x轴,而非疾病亚型,导致数据格式转换时出现类型冲突。 - 聚合逻辑偏差:
agg({'count'})统计的是各列非空值数量,并非特征的类别频率(如survival的lts/non-lts在各亚型中的占比),不符合堆叠频率图的需求。 - 数据类型混乱:原始数据中数值型列(如
patient.days_to_death)以字符串形式存储,后续聚合后类型冲突,触发运算错误。
分步解决代码
1. 数据预处理:修正数据类型
将字符串格式的数值列转为数值类型,连续值(如年龄)分箱以便统计频率:
# 转换数值型列 df['patient.days_to_death'] = pd.to_numeric(df['patient.days_to_death'], errors='coerce') df['patient.age_at_initial_pathologic_diagnosis'] = pd.to_numeric(df['patient.age_at_initial_pathologic_diagnosis'], errors='coerce') df['patient.karnofsky_performance_score'] = pd.to_numeric(df['patient.karnofsky_performance_score'], errors='coerce') # 年龄分箱,方便统计频率 df['age_group'] = pd.cut(df['patient.age_at_initial_pathologic_diagnosis'], bins=[0,50,70,100], labels=['<50','50-70','>70'])
2. 统计特征类别频率
针对分类特征,统计各疾病亚型下的类别数量:
# 选择需要统计的分类特征 features = ['survival', 'age_group', 'patient.vital_status', 'patient.gender'] # 遍历特征生成频率数据 freq_dfs = [] for feature in features: freq_df = df.groupby(['admin.disease_code', feature]).size().reset_index(name='count') freq_df['feature'] = feature # 标记所属特征,用于后续子图展示 freq_dfs.append(freq_df) # 合并所有特征的频率数据 final_df = pd.concat(freq_dfs, ignore_index=True) final_df.rename(columns={'admin.disease_code':'subtype'}, inplace=True)
3. 绘制堆叠条形图
使用Plotly生成按亚型分组、特征类别堆叠的条形图:
fig = px.bar(final_df, x='subtype', y='count', color=final_df.columns[1], # 自动匹配特征类别列 facet_col='feature', barmode='stack', title="RCC亚型临床信息特征频率堆叠图", labels={'count':'样本数量', 'subtype':'疾病亚型'}) # 调整布局,优化展示效果 fig.update_layout( facet_col_wrap=2, # 每行显示2个子图 height=600, width=1000 ) fig.show()
完整可运行代码
import pandas as pd import numpy as np import plotly.express as px # 构造示例数据(替换为你的原始数据即可) df = pd.DataFrame({ 'admin.disease_code': ['kirp','kirp','kirp','kirp','kirp','kich','kich','kich'], 'patient.days_to_death': [np.nan, np.nan, np.nan, '1771', np.nan, '980', np.nan, '1200'], 'patient.age_at_initial_pathologic_diagnosis': ['53','71','71','67','80','45','62','75'], 'patient.karnofsky_performance_score': [np.nan]*8, 'tcga_id': ['TCGA-2K-A9WE-01A','TCGA-2Z-A9J1-01A','TCGA-2Z-A9J2-01A','TCGA-2Z-A9J3-01A','TCGA-2Z-A9J5-01A','TCGA-3K-A9WX-01A','TCGA-3Z-A9J6-01A','TCGA-4Z-A9J7-01A'], 'survival': ['lts','lts','lts','non-lts','lts','non-lts','lts','non-lts'], 'patient.vital_status': [np.nan, 'Alive', np.nan, 'Dead', np.nan, 'Dead', 'Alive', 'Dead'], 'patient.gender': ['Male','Female','Male','Male','Female','Female','Male','Female'] }) # 数据预处理 df['patient.days_to_death'] = pd.to_numeric(df['patient.days_to_death'], errors='coerce') df['patient.age_at_initial_pathologic_diagnosis'] = pd.to_numeric(df['patient.age_at_initial_pathologic_diagnosis'], errors='coerce') df['patient.karnofsky_performance_score'] = pd.to_numeric(df['patient.karnofsky_performance_score'], errors='coerce') df['age_group'] = pd.cut(df['patient.age_at_initial_pathologic_diagnosis'], bins=[0,50,70,100], labels=['<50','50-70','>70']) # 统计特征频率 features = ['survival', 'age_group', 'patient.vital_status', 'patient.gender'] freq_dfs = [] for feature in features: freq_df = df.groupby(['admin.disease_code', feature]).size().reset_index(name='count') freq_df['feature'] = feature freq_dfs.append(freq_df) final_df = pd.concat(freq_dfs, ignore_index=True) final_df.rename(columns={'admin.disease_code':'subtype'}, inplace=True) # 绘制堆叠条形图 fig = px.bar(final_df, x='subtype', y='count', color=final_df.columns[1], facet_col='feature', barmode='stack', title="RCC亚型临床信息特征频率堆叠图", labels={'count':'样本数量', 'subtype':'疾病亚型'}) fig.update_layout( facet_col_wrap=2, height=600, width=1000 ) fig.show()
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

