You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame两类样本差值计算问题求助

解决DataFrame的两类标准化操作问题

操作1:按Book_No分组减去control样本的均值

需求

针对Smell、Taste、Odour、Volatility列,按Book_No分组计算control样本的各列均值,再将同Book_No的Sample A、Sample B、Sample C的对应列值减去该均值,control样本保持原值。

原始DataFrame

Book_No  Replicate    Sample  Smell  Taste  Odour  Volatility                    Notes
0   12, 43          1   control    0.3   10.0     71           1                      NaN
1   12, 43          2   control    0.4    8.0     63           3                      NaN
2   12, 43          3   control    0.1    3.0     22           2                      NaN
3   19, 21          1   control    1.1    2.0     80           3                      NaN
4   19, 21          2   control    0.4    8.0      0           4                      NaN
5   19, 21          3   control    0.9    3.0      4           6                      NaN
6   19, 21          4   control    2.1    6.0     50           4                      NaN
7   11, 22          1   control    3.4    3.0     23           3                      NaN
8   12, 43          1  Sample A    1.1   11.2     75           7                      NaN
9   12, 43          2  Sample A    1.4    3.3     87           6  Temperature was too hot
10  12, 43          3  Sample A    0.7    7.4     91           5                      NaN
11  19, 21          1  Sample B    2.1    3.2     99           7                      NaN
12  19, 21          2  Sample B    2.2   11.3     76           8                      NaN
13  19, 21          3  Sample B    1.9    9.3     89           9     sample spilt by user
14  19, 21          1  Sample C    3.2    4.0    112          10                      NaN
15  19, 21          2  Sample C    2.1    5.0     96          15                      NaN
16  19, 21          3  Sample C    2.7    7.0    105          13             Was too cold
17  11, 22          1  Sample C    2.4    3.0    121          19                      NaN

错误尝试分析

你之前的代码错误在于分组时包含了Sample列,导致计算的是每个Book_No+Sample的均值,而非仅control样本的分组均值;掩码逻辑也无法正确匹配control数据。

正确解决方案

import pandas as pd

# 加载原始DataFrame(若已存在可跳过此步)
df = pd.DataFrame({
    'Book_No': ['12, 43', '12, 43', '12, 43', '19, 21', '19, 21', '19, 21', '19, 21', '11, 22',
                '12, 43', '12, 43', '12, 43', '19, 21', '19, 21', '19, 21', '19, 21', '19, 21',
                '19, 21', '11, 22'],
    'Replicate': [1,2,3,1,2,3,4,1,1,2,3,1,2,3,1,2,3,1],
    'Sample': ['control','control','control','control','control','control','control','control',
               'Sample A','Sample A','Sample A','Sample B','Sample B','Sample B','Sample C','Sample C','Sample C','Sample C'],
    'Smell': [0.3,0.4,0.1,1.1,0.4,0.9,2.1,3.4,1.1,1.4,0.7,2.1,2.2,1.9,3.2,2.1,2.7,2.4],
    'Taste': [10.0,8.0,3.0,2.0,8.0,3.0,6.0,3.0,11.2,3.3,7.4,3.2,11.3,9.3,4.0,5.0,7.0,3.0],
    'Odour': [71,63,22,80,0,4,50,23,75,87,91,99,76,89,112,96,105,121],
    'Volatility': [1,3,2,3,4,6,4,3,7,6,5,7,8,9,10,15,13,19],
    'Notes': [pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,'Temperature was too hot',pd.NA,pd.NA,pd.NA,'sample spilt by user',pd.NA,pd.NA,'Was too cold',pd.NA]
})

# 1. 计算control样本的Book_No分组均值
control_means = df[df['Sample'] == 'control'].groupby('Book_No')[['Smell', 'Taste', 'Odour', 'Volatility']].mean().add_suffix('_mean')

# 2. 合并均值到原DataFrame
df_merged = df.merge(control_means, on='Book_No', how='left')

# 3. 对非control样本执行减法
target_cols = ['Smell', 'Taste', 'Odour', 'Volatility']
for col in target_cols:
    df_merged.loc[df_merged['Sample'] != 'control', col] = df_merged[col] - df_merged[f'{col}_mean']

# 4. 移除临时列并恢复原列顺序
df_result1 = df_merged.drop([f'{col}_mean' for col in target_cols], axis=1)[df.columns]

print(df_result1.round(4))

预期结果

Book_No  Replicate    Sample     Smell  Taste  Odour  Volatility                    Notes
0   12, 43          1   control  0.300000  10.00   71.0        1.00                      NaN
1   12, 43          2   control  0.400000   8.00   63.0        3.00                      NaN
2   12, 43          3   control  0.100000   3.00   22.0        2.00                      NaN
3   19, 21          1   control  1.100000   2.00   80.0        3.00                      NaN
4   19, 21          2   control  0.400000   8.00    0.0        4.00                      NaN
5   19, 21          3   control  0.900000   3.00    4.0        6.00                      NaN
6   19, 21          4   control  2.100000   6.00   50.0        4.00                      NaN
7   11, 22          1   control  3.400000   3.00   23.0        3.00                      NaN
8   12, 43          1  Sample A  0.833333   4.20   23.0        5.00                      NaN
9   12, 43          2  Sample A  1.133333  -3.70   35.0        4.00  Temperature was too hot
10  12, 43          3  Sample A  0.433333   0.40   39.0        3.00                      NaN
11  19, 21          1  Sample B  0.975000  -1.55   65.5        2.75                      NaN
12  19, 21          2  Sample B  1.075000   6.55   42.5        3.75                      NaN
13  19, 21          3  Sample B  0.775000   4.55   55.5        4.75     sample spilt by user
14  19, 21          1  Sample C -0.200000   1.00   89.0        7.00                      NaN
15  19, 21          2  Sample C -1.300000   2.00   73.0       12.00                      NaN
16  19, 21          3  Sample C -0.700000   4.00   82.0       10.00             Was too cold
17  11, 22          1  Sample C -1.000000   0.00   98.0       16.00                      NaN

操作2:按Book_No+Replicate匹配减去control对应值

需求

当Book_No和Replicate同时匹配时,将Sample A、Sample B、Sample C的对应列值减去control的对应值,control样本保持原值。

正确解决方案

# 1. 提取control数据,以Book_No和Replicate为索引
control_data = df[df['Sample'] == 'control'].set_index(['Book_No', 'Replicate'])[['Smell', 'Taste', 'Odour', 'Volatility']].add_suffix('_control')

# 2. 合并control数据到原DataFrame
df_merged2 = df.merge(control_data, left_on=['Book_No', 'Replicate'], right_index=True, how='left')

# 3. 对非control样本执行减法
for col in target_cols:
    df_merged2.loc[df_merged2['Sample'] != 'control', col] = df_merged2[col] - df_merged2[f'{col}_control']

# 4. 移除临时列并恢复原列顺序
df_result2 = df_merged2.drop([f'{col}_control' for col in target_cols], axis=1)[df.columns]

print(df_result2)

预期结果

Book_No  Replicate    Sample  Smell  Taste  Odour  Volatility                    Notes
0   12, 43          1   control    0.3   10.0     71           1                      NaN
1   12, 43          2   control    0.4    8.0     63           3                      NaN
2   12, 43          3   control    0.1    3.0     22           2                      NaN
3   19, 21          1   control    1.1    2.0     80           3                      NaN
4   19, 21          2   control    0.4    8.0      0           4                      NaN
5   19, 21          3   control    0.9    3.0      4           6                      NaN
6   19, 21          4   control    2.1    6.0     50           4                      NaN
7   11, 22          1   control    3.4    3.0     23           3                      NaN
8   12, 43          1  Sample A    0.8    1.2      4           6                      NaN
9   12, 43          2  Sample A    1.0   -4.7     24           3  Temperature was too hot
10  12, 43          3  Sample A    0.6    4.4     69           3                      NaN
11  19, 21          1  Sample B    1.0    1.2     19           4                      NaN
12  19, 21          2  Sample B    1.8    3.3     76           4                      NaN
13  19, 21          3  Sample B    1.0    6.3     85           3     sample spilt by user
14  19, 21          1  Sample C    2.1    2.0     32           7                      NaN
15  19, 21          2  Sample C    1.7   -3.0     96          11                      NaN
16  19, 21          3  Sample C    1.8    4.0    101           7             Was too cold
17  11, 22          1  Sample C   -1.0    0.0     98          16                      NaN

内容的提问来源于stack exchange,提问作者Steve..Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:37:13