当前位置: 首页 > 知识库问答 >
问题:

用于多个组的数据透视表

酆君墨
2023-03-14

我有一个熊猫数据帧,比如:

%pylab inline

import seaborn as sns
sns.set(color_codes=True)

import pandas as pd
import numpy as np
df = pd.DataFrame({"user_id": [1, 2, 3, 4, 5,
                          6, 7, 8, 9],
    "is_sick": [0, 0, 0, 0, 0,
                          0, 1, 1, 1],
                    "sex": ["male", "female", "male", "female", "female",
                          "male", "male", "female", "female"],
                    "age_group": ["young", "old", "old", "young",
                          "small", "old", "young", "young",
                          "old"],
                    "metric_1": [1, 2, 2, 3, 3, 4, 5, 6, 7]})
df['date'] = '2019-01-01'
df['qcut_metric_1'] = pd.qcut(df.metric_1, [0, .25, .5, .66, .75, .97, 1])

# make some more data
df_2 = df.copy()
df_2['date'] = '2019-02-01'
df = pd.concat([df, df_2])

现在,我想计算每个标准箱的每个组/队列的患病人数百分比[(性别),(年龄组),(性别,年龄组)]

注意,我知道一个单一的聚合,即sex可能类似于:

df['sick_percentage__sex'] = df.groupby(['sex']).is_sick.transform(pd.Series.mean)

一张天真的桌子可能看起来像:

pd.pivot_table(df, values='sick_percentage__sex', index=['qcut_metric_1', 'sex'], columns=[], aggfunc=np.mean)

会看起来像:

        sick_percentage__sex
qcut_metric_1   sex 
(0.999, 2.0]    female  0.40
male    0.25
(2.0, 3.0]  female  0.40
(3.0, 4.28] male    0.25
(4.28, 5.0] male    0.25
(5.0, 6.76] female  0.40
(6.76, 7.0] female  0.40

但这并不适合显示bin的度量(qcut_metric_1)和所有队列([(性),(age_group),(性,age_group)])的患病百分比。这怎么能适应呢?也许使用多维聚合?

所需的输出格式:

qcut_metric_1, cohort, percentage_of_sickness

np。平均值as pivot聚合函数可能会提供扭曲的结果(因为如果每个组的用户数不是常数,则分组平均值的平均值可能不可交换)。因此,我需要使用加权平均值。我更新了样本数据集。

agg = df.groupby(['sex']).agg({'user_id':pd.Series.nunique, 'is_sick':pd.Series.mean})
agg.columns = ['unique_users', 'sick_percentage__sex']
df = df.merge(agg, on='sex')

现在为数据透视表的输入提供数据帧。

但是现在我也在和加权均值的语法做斗争:

def wavg(x):
    print(x)
    return np.average(x['sick_percentage__sex'], weights= x['unique_users'])

作为数据透视表pd。pivot_table(df,values=['sick_percentage_uusex','unique_users',index=['qcut_metric_1','sex'],columns=[],aggfunc=wavg)只向函数传递单个序列(而不是两个序列(值权重))。

共有1个答案

鲁鹏
2023-03-14

也许透视表不是解决问题的正确方法。

一个最小的解决方案可以像下面的代码一样遍历所有队列。

是否有可能找到更有效的解决方案?我的输入文件是120G一个未压缩的CSV/当压缩通过gzip 3GB仍然翻译到大约35GB的熊猫内存需求。

%pylab inline

import seaborn as sns
sns.set(color_codes=True)

import pandas as pd
import numpy as np
df = pd.DataFrame({"user_id": [1, 2, 3, 4, 5,
                          6, 7, 8, 9],
    "is_sick": [0, 0, 0, 0, 0,
                          0, 1, 1, 1],
                    "sex": ["male", "female", "male", "female", "female",
                          "male", "male", "female", "female"],
                    "age_group": ["young", "old", "old", "young",
                          "small", "old", "young", "young",
                          "old"],
                    "metric_1": [1, 2, 2, 3, 3, 4, 5, 6, 7]})
df['date'] = '2019-01-01'
df['qcut_metric_1'] = pd.qcut(df.metric_1, [0, .25, .5, .66, .75, .97, 1])

# make some more data
df_2 = df.copy()
df_2['date'] = '2019-02-01'
df = pd.concat([df, df_2])
cohorts = [['sex', 'age_group'], ['sex'], ['age_group']]
for cohort in cohorts:
    cohort_name = '_'.join(cohort)
    # print(cohort_name)
    agg = df.groupby(cohort).agg({'user_id':pd.Series.nunique, 'is_sick':pd.Series.mean})
    sick_percentage_column = f'sick_percentage__{cohort_name}'
    agg.columns = ['unique_users', sick_percentage_column]
    merged = df.merge(agg, on=cohort) # INNER (default) JOIN ok, as agg derived from total => no values lost

    groupings = ['qcut_metric_1']
    groupings.extend(cohort)
    result = merged.groupby(groupings).apply(lambda x: np.average(x[sick_percentage_column], weights= x['unique_users'])).reset_index().rename({0:sick_percentage_column}, axis=1)
    display(result)    
 类似资料:
  • D.1 组合日期数据 前面我们使用地区、城市、产品名称、雇员等字段作为分类字段查看数据汇总信息。那么如果我们按照订单日期做为分类字段来查看汇总信息会是什么样呢?将“订单日期”字段拖动到“行标签”区域,所生成数据透视表如下图所示:此数据透视表显示的是每一天的金额合计,显然不是我们所期望的结果。如果我们希望按照年、季度、月份等来计算金额的汇总信息又该如何实现呢?可以直接在日期字段上单击鼠标右键,选择“

  • 问题内容: 我是一起定义关系和框架的新手,我只是习惯于原始SQL。我做了家庭作业(google + Laravel文档),但是我认为我不太了解它。 以下是相关信息:用户表: 挑战表: User_challenge_links Challenge_sub_categories 所以我的目标..用户->挑战。 关系: 一个用户有许多User_challenge_links 一个User_challen

  • 问题内容: 我有一个产生以下结果集的视图: 我需要将其转换为: 我只使用交叉表使用列,就知道该怎么做。如何在目标结果集中使用和产生新列?如果我只是在查询中添加列,它会抱怨“无效的源数据SQL语句”。 我正在使用PostgreSQL 9.3.6。 问题答案: 一种方法是使用复合类型: 或者,为临时使用(在会话期间注册类型): 然后,根据需要运行交叉表并分解复合类型: 所有括号都是 必需的 ! 基础知

  • A 数据透视表介绍 B.1 什么是数据透视表? 数据透视表是一种可以快速汇总、分析大量数据表格的交互式工具。使用数据透视表可以按照数据表格的不同字段从多个角度进行透视,并建立交叉表格,用以查看数据表格不同层面的汇总信息、分析结果以及摘要数据。使用数据透视表可以深入分析数值数据,以帮助用户发现关键数据,并做出有关企业中关键数据的决策。 数据透视表是针对以下用途特别设计的:以友好的方式,查看大量的数据

  • 数据透视表显示二维交集的度量值,并在表格视图中表示数据。 图表属性 选择图表类型后,可以更改其属性来自定义图表: 选项 描述 常规 背景颜色 设置图表区域的背景颜色。 不透明度 设置背景颜色的不透明度。 显示边框 显示图表外部边框。 边界颜色 设置图表外部边框的颜色。 显示标题 显示图表的主要标题。 标题 指定图表的标题。 标题字体 设置标题的字体样式。 位置 设置标题的位置。 对齐 设置标题的水

  • 数据透视表显示二维交集的度量值,并在表格视图中表示数据。 图表属性 选择图表类型后,可以更改其属性来自定义图表: 选项 描述 常规 背景颜色 设置图表区域的背景颜色。 显示边框 显示图表外部边框。 边界颜色 设置图表外部边框的颜色。 显示标题 显示图表的主要标题。 标题 指定图表的标题。 标题字体 设置标题的字体样式。 位置 设置标题的位置。 对齐 设置标题的水平对齐方式。 数据 字体 设置字段名