【问题标题】:How can I create a new column containing the same values as a groupby in a Pandas Dataframe?如何在 Pandas 数据框中创建一个包含与 groupby 相同值的新列?
【发布时间】:2021-11-10 03:16:36
【问题描述】:

我有一个需要为其创建新列的数据集。这个新列需要与在 groupby 中找到的值等效。

例如:

我有这个数据框:

data = [
    ["A", 1, "special","aaa", 64],
    ["A", 1,"special", "bbb", 140],
    ["A", 2,"notspecial", "aaa", 25],
    ["A", 2,"notspecial", "bbb", 12],
    ["A", 3,"notspecial", "aaa", 85],
    ["A", 3,"notspecial", "bbb", 10],
    ["B", 1,"special", "ccc", 200],
    ["B", 2,"notspecial", "ccc", 350],
    ["B", 3,"notspecial", "ccc", 500],
    ["B", 4,"notspecial", "ccc", 651],

]

df = pd.DataFrame(data, columns=["ID", "Subset", "Description","Category", "Value"])
df

我需要使用新列创建此数据集的版本,此新列需要是 special 行的 Value,由 IDCategory 分组。 (请注意,在某些情况下,不会有多个类别,而在某些情况下会有)。基本上,整列仅包含 IDCategory groupby 的 special 值。如下:

data = [
    ["A", 1, "special", "aaa", 64, 64],
    ["A", 1, "special", "bbb", 140, 140],
    ["A", 2, "notspecial", "aaa", 25, 64],
    ["A", 2, "notspecial", "bbb", 12, 140],
    ["A", 3, "notspecial", "aaa", 85, 64],
    ["A", 3, "notspecial", "bbb", 10, 140],
    ["B", 1, "special", "ccc", 200, 200],
    ["B", 2, "notspecial", "ccc", 350, 200],
    ["B", 3, "notspecial", "ccc", 500, 200],
    ["B", 4, "notspecial", "ccc", 651, 200],
]

df = pd.DataFrame(
    data, columns=["ID", "Subset", "Description", "Category", "Value", "special_value"]
)
df

我以前用过:

# create new column dedicated to untreated mean raw value severity values across trial ids
df["special_value"] = (
    df.where(
        df["Description"].eq("special")
    )
    .groupby(["ID", "Category"])["Value"]
    .transform("mean")
)

但这仅适用于 groupby 只是 ID 而不是当我添加 Category 时。

任何帮助将不胜感激!

谢谢!

【问题讨论】:

  • 我不太明白。你能包括预期的输出吗?
  • 我用第二个屏幕截图和数据框做了! special_value 列是我要创建的新列。我还添加了一些希望澄清的编辑。

标签: python pandas dataframe group-by


【解决方案1】:

IIUC,您可以使用pandas.DataFrame.groupby.transformfirst

df["special_value"] = df["Value"][df["Description"].eq("special")]
df["special_value"] = df.groupby("Category")["special_value"].transform("first")
print(df)

输出:

  ID  Subset Description Category  Value  special_value
0  A       1     special      aaa     64           64.0
1  A       1     special      bbb    140          140.0
2  A       2  notspecial      aaa     25           64.0
3  A       2  notspecial      bbb     12          140.0
4  A       3  notspecial      aaa     85           64.0
5  A       3  notspecial      bbb     10          140.0
6  B       1     special      ccc    200          200.0
7  B       2  notspecial      ccc    350          200.0
8  B       3  notspecial      ccc    500          200.0
9  B       4  notspecial      ccc    651          200.0

【讨论】:

  • 啊,这太接近了。唯一的问题是它不适用于没有多个类别的情况,即 ID B。
  • @user 你能解释一下吗?或者更好的是,更新您的样本以反映此类情况;)
  • 哦,天哪,我的错误,现在就这样做!我相信它反映在ID = B, category = ccc`。当我运行您包含的代码时,我得到了所有 np.nan 值而不是 200。非常感谢您的帮助!!!!
  • 我认为样本的ccc 的第一行是错字(它不特殊,而输出是特殊的)但也许我错了。如果还没有,您是否必须明确地将每个组的第一行转换为特殊行?
  • 不,你是对的!我的错误还在继续。谢谢 !!!! (再次抱歉)
【解决方案2】:

这是一种方法,如果您想要 ID 和 Category 的第一个值,否则您可以使用 groupby 执行相同的创建 dfm:

dfm =df.query("Description =='special").drop_duplicates(['ID','Category'])[['ID', 'Category', 'Value']]\
       .rename(columns={'Value':'special_value_comp'})
df.merge(dfm, on=['ID', 'Category']).sort_values(['ID', 'Subset'])

输出:

  ID  Subset Description Category  Value  special_value  special_value_comp
0  A       1     special      aaa     64             64                  64
3  A       1     special      bbb    140            140                 140
1  A       2  notspecial      aaa     25             64                  64
4  A       2  notspecial      bbb     12            140                 140
2  A       3  notspecial      aaa     85             64                  64
5  A       3  notspecial      bbb     10            140                 140
6  B       1     special      ccc    200            200                 200
7  B       2  notspecial      ccc    350            200                 200
8  B       3  notspecial      ccc    500            200                 200
9  B       4  notspecial      ccc    651            200                 200

【讨论】:

  • @user 是的,我忘记了那个条件。
  • @user 编码愉快!保持安全并保持健康。
【解决方案3】:

另一种方式

df.loc[df['Description'] != 'special', 'Value'] = np.nan
df['special_value'] = df.groupby(["ID", "Category"]).Value.transform(lambda x: x.fillna(x.mean()))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-11
    • 2021-04-13
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多