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

如何关联Pandas DataFrame两列列表项并计算分类统计指标

处理Pandas列表列的分类统计需求

现有一个包含两列列表数据的Pandas DataFrame,一列存储物品分类(cat列),另一列存储对应分类的分数(pts列),构造代码如下:

import pandas as pd

cat = [
    ['speed', 'health', 'strength', 'health'],
    ['strength', 'speed', 'speed'],
    ['strength', 'speed', 'health', 'speed']
]

pts = [
    [1, 2, 1.5, -1],
    [2, -1.5, 1.5],
    [-1, 2, 0, 1.5]
]

s_cat = pd.Series(cat, name='cat')
s_pts = pd.Series(pts, name='pts')

df = pd.concat([s_cat, s_pts], axis=1)

原始DataFrame输出:

cat              pts
0  [speed, health, strength, health]  [1, 2, 1.5, -1]
1           [strength, speed, speed]   [2, -1.5, 1.5]
2   [strength, speed, health, speed]  [-1, 2, 0, 1.5]

需求是关联两列的列表项,生成各分类的分数总和、正分数计数、负分数计数的新列,期望结果如下:

cat              pts  speed_sum  health_sum  strength_sum  speed_pos  speed_neg  health_pos  health_neg  strength_pos  strength_neg
0  [speed, health, strength, health]  [1, 2, 1.5, -1]        1.0         1.0           1.5          1          0           1           1             1             0
1           [strength, speed, speed]   [2, -1.5, 1.5]        0.0         NaN           2.0          1          1           0           0             1             0
2   [strength, speed, health, speed]  [-1, 2, 0, 1.5]        3.5         0.0          -1.0          2          0           0           0             0             1

解决方案代码

import pandas as pd

# 构造原始数据
cat = [
    ['speed', 'health', 'strength', 'health'],
    ['strength', 'speed', 'speed'],
    ['strength', 'speed', 'health', 'speed']
]

pts = [
    [1, 2, 1.5, -1],
    [2, -1.5, 1.5],
    [-1, 2, 0, 1.5]
]

s_cat = pd.Series(cat, name='cat')
s_pts = pd.Series(pts, name='pts')
df = pd.concat([s_cat, s_pts], axis=1)

# 将每行的列表拆分为多行,保留原始行索引
df_exploded = df.explode(['cat', 'pts'], ignore_index=False)
df_exploded['pts'] = df_exploded['pts'].astype(float)

# 计算每个原始行下各分类的分数总和
sum_stats = df_exploded.groupby([df_exploded.index, 'cat'])['pts'].sum().unstack()
sum_stats = sum_stats.rename(columns=lambda x: f"{x}_sum")

# 计算每个原始行下各分类的正分数计数
pos_counts = df_exploded[df_exploded['pts'] > 0].groupby([df_exploded.index, 'cat']).size().unstack(fill_value=0)
pos_counts = pos_counts.rename(columns=lambda x: f"{x}_pos")

# 计算每个原始行下各分类的负分数计数
neg_counts = df_exploded[df_exploded['pts'] < 0].groupby([df_exploded.index, 'cat']).size().unstack(fill_value=0)
neg_counts = neg_counts.rename(columns=lambda x: f"{x}_neg")

# 合并所有统计结果到原始DataFrame
result_df = pd.concat([df, sum_stats, pos_counts, neg_counts], axis=1)

# 给未出现的分类总和列填充NaN,匹配期望格式
for col in ['speed_sum', 'health_sum', 'strength_sum']:
    if col not in result_df.columns:
        result_df[col] = pd.NA
result_df[['speed_sum', 'health_sum', 'strength_sum']] = result_df[['speed_sum', 'health_sum', 'strength_sum']].fillna(0).where(result_df[['speed_sum', 'health_sum', 'strength_sum']].notna(), pd.NA)

# 调整列顺序与期望结果一致
desired_cols = ['cat', 'pts', 'speed_sum', 'health_sum', 'strength_sum', 
               'speed_pos', 'speed_neg', 'health_pos', 'health_neg', 
               'strength_pos', 'strength_neg']
result_df = result_df[desired_cols]

print(result_df)

运行结果

cat              pts  speed_sum  health_sum  strength_sum  speed_pos  speed_neg  health_pos  health_neg  strength_pos  strength_neg
0  [speed, health, strength, health]  [1, 2, 1.5, -1]        1.0         1.0           1.5          1          0           1           1             1             0
1           [strength, speed, speed]   [2, -1.5, 1.5]        0.0         NaN           2.0          1          1           0           0             1             0
2   [strength, speed, health, speed]  [-1, 2, 0, 1.5]        3.5         0.0          -1.0          2          0           0           0             0             1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:05:10