如何拆分数据列字符串转整数?血压与健康、睡眠的相关性分析
问题背景
我正在处理如下数据集,目标是分析血压对患者的影响:
df = {'Person ID': [1,2,3,4,5,6,7,8], 'BMI': ['Overweight','Normal','Normal','Obese','Obese','Underweight','Normal','Obese'], 'Sleep Disorder': ['Insomnia',float('nan'),float('nan'),'Sleep Apnea','Sleep Apnea',float('nan'),float('nan'),'Insomnia'], 'Illness':['Ill', 'Healthy','Healthy','Ill','Ill','Healthy','Healthy','Ill'], 'Blood Pressure': ['125/82','132/87','128/85','126/83','126/83','115/78','139/91','142/92']}
数据集输出如下:
Person ID BMI Sleep Disorder Illness Blood Pressure Sleep Duration 0 1 Overweight Insomnia Ill 125/82 6.1 1 2 Normal NaN Healthy 132/87 6.2 2 3 Normal NaN Healthy 128/85 6.2 3 4 Obese Sleep Apnea Ill 126/83 5.9 4 5 Obese Sleep Apnea Ill 126/83 5.9 5 6 Underweight NaN Healthy 115/78 8.1 6 7 Normal NaN Healthy 139/91 8.1 7 8 Obese Insomnia Ill 142/92 8.1
核心问题:Blood Pressure列是字符串类型,无法直接计算相关性;同时不确定用哪种方法对比Ill和Healthy人群的血压差异。原本想复用以下代码分析血压与睡眠时长的关系,但因为数据类型问题无法实现:
graph_bp = sns.scatterplot(data = sleep_dataset, x = "Blood Pressure", y = "Sleep Duration", hue = "Health State") graph_bp.set_title("Relation between age and sleep duration") graph_bp.set_xlabel("Blood Pressure") graph_bp.set_ylabel("Sleep Duration") cor_bp = sleep_dataset["Blood Pressure"].corr(sleep_dataset["Sleep Duration"]) print("Correlation with age: " + str(cor_bp))
曾考虑拆分收缩压和舒张压取差值,但该方法有缺陷(比如140/100与100/60差值相同,但实际血压情况差异很大),想请教如何处理该列数据以进行相关性分析及可视化?
解决方案
1. 拆分收缩压和舒张压为数值列
最合理的处理方式是将字符串格式的血压拆分为**收缩压(Systolic)和舒张压(Diastolic)**两个独立的数值列——两者有独立的临床意义,不能用差值替代。
用Pandas处理的代码如下:
import pandas as pd # 转换为DataFrame sleep_dataset = pd.DataFrame(df) # 拆分血压列并转为整数类型 sleep_dataset[['Systolic', 'Diastolic']] = sleep_dataset['Blood Pressure'].str.split('/', expand=True).astype(int)
处理后数据集会新增两个整数列,后续所有分析都基于这两列开展。
2. 相关性与差异分析方法
(1)血压与睡眠时长的相关性
睡眠时长、收缩压/舒张压均为连续数值,直接用皮尔逊相关系数计算即可:
# 计算收缩压与睡眠时长的相关性 cor_systolic = sleep_dataset["Systolic"].corr(sleep_dataset["Sleep Duration"]) # 计算舒张压与睡眠时长的相关性 cor_diastolic = sleep_dataset["Diastolic"].corr(sleep_dataset["Sleep Duration"]) print(f"收缩压与睡眠时长的相关性: {cor_systolic:.2f}") print(f"舒张压与睡眠时长的相关性: {cor_diastolic:.2f}")
(2)Ill/Healthy人群的血压差异对比
由于样本量较小(每组仅4个样本),推荐用曼-惠特尼U检验(非参数检验,不依赖正态分布假设);若假设数据符合正态分布,也可使用独立样本t检验。
示例代码(曼-惠特尼U检验):
from scipy.stats import mannwhitneyu # 拆分两组数据 ill_systolic = sleep_dataset[sleep_dataset['Illness'] == 'Ill']['Systolic'] healthy_systolic = sleep_dataset[sleep_dataset['Illness'] == 'Healthy']['Systolic'] ill_diastolic = sleep_dataset[sleep_dataset['Illness'] == 'Ill']['Diastolic'] healthy_diastolic = sleep_dataset[sleep_dataset['Illness'] == 'Healthy']['Diastolic'] # 检验收缩压组间差异 stat_systolic, p_systolic = mannwhitneyu(ill_systolic, healthy_systolic) # 检验舒张压组间差异 stat_diastolic, p_diastolic = mannwhitneyu(ill_diastolic, healthy_diastolic) print(f"收缩压组间差异检验p值: {p_systolic:.3f}") print(f"舒张压组间差异检验p值: {p_diastolic:.3f}")
若p值小于0.05,说明两组的血压存在统计学差异。
3. 可视化方案
(1)血压与睡眠时长的散点图
分别绘制收缩压、舒张压与睡眠时长的散点图,用hue区分健康状态:
import seaborn as sns import matplotlib.pyplot as plt # 收缩压 vs 睡眠时长 plt.figure(figsize=(10, 5)) graph_systolic = sns.scatterplot(data=sleep_dataset, x="Systolic", y="Sleep Duration", hue="Illness") graph_systolic.set_title("收缩压与睡眠时长的关系") graph_systolic.set_xlabel("收缩压") graph_systolic.set_ylabel("睡眠时长") plt.show() # 舒张压 vs 睡眠时长 plt.figure(figsize=(10, 5)) graph_diastolic = sns.scatterplot(data=sleep_dataset, x="Diastolic", y="Sleep Duration", hue="Illness") graph_diastolic.set_title("舒张压与睡眠时长的关系") graph_diastolic.set_xlabel("舒张压") graph_diastolic.set_ylabel("睡眠时长") plt.show()
(2)Ill/Healthy人群的血压箱线图
用箱线图直观展示两组的血压分布差异:
# 收缩压组间对比箱线图 plt.figure(figsize=(8, 5)) sns.boxplot(data=sleep_dataset, x="Illness", y="Systolic") plt.title("健康/患病人群的收缩压分布") plt.xlabel("健康状态") plt.ylabel("收缩压") plt.show() # 舒张压组间对比箱线图 plt.figure(figsize=(8, 5)) sns.boxplot(data=sleep_dataset, x="Illness", y="Diastolic") plt.title("健康/患病人群的舒张压分布") plt.xlabel("健康状态") plt.ylabel("舒张压") plt.show()
内容的提问来源于stack exchange,提问作者Manuel Veiga
相关产品推荐
相关产品推荐

