如何使用一列或另一列对 pandas DataFrame 进行分组
How do I group a pandas DataFrame using one column or another
尊敬的 pandas DataFrame 专家,
我一直在使用 pandas DataFrames 来帮助重写开源项目中的图表代码 (https://openrem.org/, https://bitbucket.org/openrem/openrem)。
我一直在对 study_name 和 x_ray_system_name 等字段的数据进行分组和聚合。
示例数据框可能包含以下数据:
study_name request_name total_dlp x_ray_system_name
head head 50.0 All systems
head head 100.0 All systems
head NaN 200.0 All systems
blank NaN 75.0 All systems
blank NaN 125.0 All systems
blank head 400.0 All systems
下一行计算按 x_ray_system_name 和 study_name 分组的 total_dlp 数据的计数和平均值:
df.groupby(["x_ray_system_name", "study_name"]).agg({"total_dlp": ["count", "mean"]})
结果如下:
total_dlp
count mean
x_ray_system_name study_name
All systems blank 3 200.000000
head 3 116.666667
我现在需要能够计算 total_dlp 数据分组的平均值 study_name 或 request_name .所以在上面的例子中,我希望“head”意味着包括三个 study_name“head”条目,以及单个 request_name“head”条目。
我希望结果看起来像这样:
total_dlp
count mean
x_ray_system_name name
All systems blank 3 200.000000
head 4 187.500000
有谁知道如何根据一个或另一个字段中的类别进行分组?
非常感谢您提供的任何帮助。
亲切的问候,
大卫
您(groupby)数据本质上是以下的并集:
- 用
study_name == request_name
提取那些
- 与
study_name != request_name
重复,一个用于 study_name
,一个用于 request_name
我们可以用melt
复制数据
(pd.concat([df.query('study_name==request_name') # equal part
.drop('request_name', axis=1), # remove so `melt` doesn't duplicate this data
df.query('study_name!=request_name')]) # not equal part
.melt(['x_ray_system_name','total_dlp']) # melt to duplicate
.groupby(['x_ray_system_name','value'])
['total_dlp'].mean()
)
更新:编辑上面的代码帮助我意识到我们可以简化 do:
# mask `request_name` with `NaN` where they equal `study_name`
# so they are ignored when duplicate/mean
(df.assign(request_name=df.request_name.mask(df.study_name==df.request_name))
.melt(['x_ray_system_name','total_dlp'])
.groupby(['x_ray_system_name','value'])
['total_dlp'].mean()
)
输出:
x_ray_system_name value
All systems blank 200.0
head 187.5
Name: total_dlp, dtype: float64
我的方法与@QuangHoang 的方法类似,但操作顺序不同。
我在这里使用原始(范围)索引来选择如何删除重复数据。
您可以 melt
、drop_duplicates
和 dropna
以及 groupby
:
(df.reset_index()
.melt(id_vars=['index', 'total_dlp', 'x_ray_system_name'])
.drop_duplicates(['index', 'value'])
.dropna(subset=['value'])
.groupby(["x_ray_system_name", 'value'])
.agg({"total_dlp": ["count", "mean"]})
)
输出:
total_dlp
count mean
x_ray_system_name value
All systems blank 3 200.0
head 4 187.5
尊敬的 pandas DataFrame 专家,
我一直在使用 pandas DataFrames 来帮助重写开源项目中的图表代码 (https://openrem.org/, https://bitbucket.org/openrem/openrem)。
我一直在对 study_name 和 x_ray_system_name 等字段的数据进行分组和聚合。
示例数据框可能包含以下数据:
study_name request_name total_dlp x_ray_system_name
head head 50.0 All systems
head head 100.0 All systems
head NaN 200.0 All systems
blank NaN 75.0 All systems
blank NaN 125.0 All systems
blank head 400.0 All systems
下一行计算按 x_ray_system_name 和 study_name 分组的 total_dlp 数据的计数和平均值:
df.groupby(["x_ray_system_name", "study_name"]).agg({"total_dlp": ["count", "mean"]})
结果如下:
total_dlp
count mean
x_ray_system_name study_name
All systems blank 3 200.000000
head 3 116.666667
我现在需要能够计算 total_dlp 数据分组的平均值 study_name 或 request_name .所以在上面的例子中,我希望“head”意味着包括三个 study_name“head”条目,以及单个 request_name“head”条目。
我希望结果看起来像这样:
total_dlp
count mean
x_ray_system_name name
All systems blank 3 200.000000
head 4 187.500000
有谁知道如何根据一个或另一个字段中的类别进行分组?
非常感谢您提供的任何帮助。
亲切的问候,
大卫
您(groupby)数据本质上是以下的并集:
- 用
study_name == request_name
提取那些
- 与
study_name != request_name
重复,一个用于study_name
,一个用于request_name
我们可以用melt
(pd.concat([df.query('study_name==request_name') # equal part
.drop('request_name', axis=1), # remove so `melt` doesn't duplicate this data
df.query('study_name!=request_name')]) # not equal part
.melt(['x_ray_system_name','total_dlp']) # melt to duplicate
.groupby(['x_ray_system_name','value'])
['total_dlp'].mean()
)
更新:编辑上面的代码帮助我意识到我们可以简化 do:
# mask `request_name` with `NaN` where they equal `study_name`
# so they are ignored when duplicate/mean
(df.assign(request_name=df.request_name.mask(df.study_name==df.request_name))
.melt(['x_ray_system_name','total_dlp'])
.groupby(['x_ray_system_name','value'])
['total_dlp'].mean()
)
输出:
x_ray_system_name value
All systems blank 200.0
head 187.5
Name: total_dlp, dtype: float64
我的方法与@QuangHoang 的方法类似,但操作顺序不同。
我在这里使用原始(范围)索引来选择如何删除重复数据。
您可以 melt
、drop_duplicates
和 dropna
以及 groupby
:
(df.reset_index()
.melt(id_vars=['index', 'total_dlp', 'x_ray_system_name'])
.drop_duplicates(['index', 'value'])
.dropna(subset=['value'])
.groupby(["x_ray_system_name", 'value'])
.agg({"total_dlp": ["count", "mean"]})
)
输出:
total_dlp
count mean
x_ray_system_name value
All systems blank 3 200.0
head 4 187.5