如何按行(按ID)计算经sqrt变换的比例(proportions)?
计算逻辑
提前明确计算规则,避免执行偏差:
- 逐行统计dogs/cats/birds/fish四个动物列的计数总和
- 每类动物的占比 = 该列当前行数值 / 当前行四类计数总和
- 对上述占比做平方根变换,得到最终结果
如果你的实际需求是先按相同Id聚合所有行的计数,再做上述计算,可以参考各工具的补充方案。
Python(Pandas实现,1w+数据秒处理)
采用向量化操作,比循环效率高数十倍,完全适配你的数据规模:
import pandas as pd import numpy as np # 假设df是你读入的原始数据集 animal_cols = ['dogs', 'cats', 'birds', 'fish'] # 计算每行四类动物的总计数 df['row_sum'] = df[animal_cols].sum(axis=1) # 批量计算各列sqrt变换后的占比,新列加_sqrt_pro后缀 for col in animal_cols: df[f'{col}_sqrt_pro'] = np.sqrt(df[col] / df['row_sum']) # 不需要中间总计数列可以直接删除 df = df.drop(columns=['row_sum'])
如果需要先按Id分组聚合后计算:
# 按Id分组,先求和所有动物列的计数 id_grouped = df.groupby('Id', as_index=False)[animal_cols].sum() # 后续计算逻辑和逐行计算完全一致 id_grouped['row_sum'] = id_grouped[animal_cols].sum(axis=1) for col in animal_cols: id_grouped[f'{col}_sqrt_pro'] = np.sqrt(id_grouped[col] / id_grouped['row_sum'])
R实现
常规tidyverse方案(适配10w条以内数据)
library(dplyr) animal_cols <- c("dogs", "cats", "birds", "fish") df <- df %>% rowwise() %>% mutate( row_sum = sum(c_across(all_of(animal_cols))), across(all_of(animal_cols), ~sqrt(.x / row_sum), .names = "{.col}_sqrt_pro") ) %>% ungroup() %>% select(-row_sum)
大数据优化方案(data.table,百万级数据也可快速处理)
library(data.table) # 转换为data.table对象提升处理效率 setDT(df) animal_cols <- c("dogs", "cats", "birds", "fish") # 计算行总计数 df[, row_sum := rowSums(.SD), .SDcols = animal_cols] # 批量计算sqrt变换后的占比 df[, paste0(animal_cols, "_sqrt_pro") := lapply(.SD, function(x) sqrt(x / row_sum)), .SDcols = animal_cols] # 删除中间列 df[, row_sum := NULL]
如果需要先按Id分组聚合后计算:
df_grouped <- df[, lapply(.SD, sum), by = Id, .SDcols = animal_cols] df_grouped[, row_sum := rowSums(.SD), .SDcols = animal_cols] df_grouped[, paste0(animal_cols, "_sqrt_pro") := lapply(.SD, function(x) sqrt(x / row_sum)), .SDcols = animal_cols] df_grouped[, row_sum := NULL]
内容的提问来源于stack exchange,提问作者user17122732
相关产品推荐
相关产品推荐

