You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Pandas将患者多小时医疗测量数据的长格式DataFrame转换为宽格式DataFrame

解决方法:将患者多小时测量数据转为单行宽格式

首先,你的思路方向是对的,但pd.concat的用法和循环逻辑出了问题,先来看正确的实现方式,再分析你的错误。

步骤1:构造示例数据

先把你给出的示例数据转换成可运行的DataFrame:

import pandas as pd

# 构造示例数据
data = {
    'patientid': [1, 1, 2, 2],
    'hour': [1, 2, 1, 2],
    'measurementx': [13.5, 13.9, 11.5, 14.9],
    'measurementy': [2030, 2013, 1890, 2009]
}
x_binary = pd.DataFrame(data)

步骤2:实现目标格式(推荐方法)

我们可以用groupby分组后,将每个患者的所有行数据展平为一维,再组合成新的DataFrame:

# 按患者ID分组,将每组的非ID列展平为一维数组
grouped = x_binary.groupby('patientid').apply(
    lambda group: group.drop('patientid', axis=1).values.flatten()
)

# 转换为DataFrame并重置索引
x_binary_compact = grouped.to_frame().reset_index()

# 生成匹配需求的列名:重复hour、measurementx、measurementy
hour_count = x_binary['hour'].nunique()
new_columns = ['patientid'] + [col for _ in range(hour_count) for col in ['hour', 'measurementx', 'measurementy']]
x_binary_compact.columns = new_columns

# 查看结果
print(x_binary_compact)

运行后会得到你想要的格式:

patientid  hour  measurementx  measurementy  hour  measurementx  measurementy
0          1     1          13.5          2030     2          13.9          2013
1          2     1          11.5          1890     2          14.9          2009

另一种方法:透视表实现

如果你习惯用透视表,也可以通过给列添加小时标识,再调整列名来实现:

# 生成带小时标识的临时列
x_binary['hour_label'] = x_binary['hour'].astype(str)

# 透视成宽格式
pivoted = x_binary.pivot(
    index='patientid',
    columns='hour_label',
    values=['hour', 'measurementx', 'measurementy']
)

# 展平多层列名,还原成重复的列名格式
pivoted.columns = [col[0] for col in pivoted.columns]

# 重置索引得到最终结果
x_binary_compact = pivoted.reset_index()

分析你的代码错误

你遇到的TypeError主要有三个原因:

  1. pd.concat用法错误pd.concat的第一个参数必须是可迭代对象(比如列表),正确写法是pd.concat([df1, df2], axis=1),而你直接传入了x_binary_compactrow,导致参数解析混乱。
  2. 数据类型不匹配itertuples返回的是元组,不是DataFrame/Series,不能直接和DataFrame拼接。
  3. 循环逻辑问题:你的拼接逻辑无法正确将同一患者的行合并到同一行,反而会导致数据结构混乱。

内容的提问来源于stack exchange,提问作者cercio

火山引擎 最新活动