如何将分组后的数据框的所有产品名称聚合到一个新列中,作为列表或集合:

import pandas as pd  # 2.0.3

df = pd.DataFrame(
    {
        "customer_id": [1, 2, 3, 2, 1],
        "order_id": [1, 2, 3, 4, 1],
        "products": ["foo", "bar", "baz", "foo", "bar"],
        "amount": [1, 1, 1, 1, 1]
    }
)

print(df)
grouped = df.groupby(["customer_id", "order_id"])
df["product_order_count"] = grouped["amount"].transform("sum")
df["all_products"] = grouped["products"].agg(list).reset_index()
print(df)

尽管我回答了另一个问题(Pandas groupby: How to get a union of strings),但抛出了一个异常:

Traceback (most recent call last):
  File "C:\temp\tt.py", line 15, in <module>
    df["all_orders"] = grouped["products"].agg(list).reset_index()
  File "c:\Users\foo\.venvs\kapa_monitor-38\lib\site-packages\pandas\core\frame.py", line 3940, in __setitem__
    self._set_item_frame_value(key, value)
  File "c:\Users\foo\.venvs\kapa_monitor-38\lib\site-packages\pandas\core\frame.py", line 4094, in _set_item_frame_value
    raise ValueError(
ValueError: Cannot set a DataFrame with multiple columns to the single column all_products

预期输出(all_products,作为listset):

   customer_id  order_id products  amount  product_order_count all_products
0            1         1      foo       1                    2 'foo', 'bar'
1            2         2      bar       1                    1 'bar'
2            3         3      baz       1                    1 'baz'
3            2         4      foo       1                    1 'foo'
4            1         1      bar       1                    2 'foo', 'bar'

推荐答案

您可以在函数中使用transform,该函数返回与组长度相同的值:

df["all_products"] = grouped["products"].transform(lambda x: [list(x)]*len(x))

输出:

   customer_id  order_id products  amount  product_order_count all_products
0            1         1      foo       1                    2   [foo, bar]
1            2         2      bar       1                    1        [bar]
2            3         3      baz       1                    1        [baz]
3            2         4      foo       1                    1        [foo]
4            1         1      bar       1                    2   [foo, bar]

或者,您可以连接字符串(我并不真正推荐数据中的列表):

df["all_products"] = grouped["products"].transform(','.join)

这给了我们

   customer_id  order_id products  amount  product_order_count all_products
0            1         1      foo       1                    2      foo,bar
1            2         2      bar       1                    1          bar
2            3         3      baz       1                    1          baz
3            2         4      foo       1                    1          foo
4            1         1      bar       1                    2      foo,bar

Python相关问答推荐

如何根据另一列值用字典中的值替换列值

仅从风格中获取 colored颜色 循环

使用SciPy进行曲线匹配未能给出正确的匹配

韦尔福德方差与Numpy方差不同

输出中带有南的亚麻神经网络

聚合具有重复元素的Python字典列表,并添加具有重复元素数量的新键

为什么抓取的HTML与浏览器判断的元素不同?

如何并行化/加速并行numba代码?

如何更新pandas DataFrame上列标题的de值?

合并帧,但不按合并键排序

OpenCV轮廓.很难找到给定图像的所需轮廓

人口全部乱序 - Python—Matplotlib—映射

循环浏览每个客户记录,以获取他们来自的第一个/最后一个渠道

我对这个简单的异步者的例子有什么错误的理解吗?

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

合并相似列表

Seaborn散点图使用多个不同的标记而不是点

对当前的鼹鼠进行编码,并且我的按键获得了注册

Fake pathlib.使用pyfakefs的类变量中的路径'

是否将列表分割为2?