python - 根据组的长度拆分和更改 pandas 'groupby' 元素的值
问题描述
我有一个 pandas DataFrame 对象,其中有一列名为'order_id'。具有相同 id 的行属于一个且相同的顺序(大小可以是 1 到 1000 之间的任何值),例如:
sales_orders = {
'order_id': [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
# multiple other fields
}
df = pd.DataFrame(sales_orders)
我需要根据截止值(例如 3)将组拆分为更小的块。理想情况下,除了列的后缀之外没有其他变化,即:
'order_id': [1-0, 1-0, 1-0, 1-1, 1-1, 1-1, 1-2, 2, 2, 2, 3-0, 3-0, 3-0, 3-1, 3-1, 3-1, 3-2, 3-2, 3-2, 4]
我假设人们可以简单地遍历这些组并在 for 循环中单独触摸每个组,如下所示:
for order_id, group in df.groupby(by=['order_id']):
if group.shape[0] > 2:
# change column line by line
但这看起来令人难以置信的 unpanda'ish 和可怕的缓慢。因此,我将不胜感激一个明智、高性能和可读的解决方案;)提前感谢您的帮助!
解决方案
使用groupby
andcumcount
获取后缀,然后使用np.where
有条件地设置它们。
c = df.groupby('order_id').cumcount() // 3
m = (c == 0).groupby(df.order_id).transform('all')
df['order_id2'] = (
np.where(m, df.order_id, df.order_id.astype(str) + '-' + c.astype(str))
.astype(str))
df.head(10)
order_id order_id2
0 1 1-0
1 1 1-0
2 1 1-0
3 1 1-1
4 1 1-1
5 1 1-1
6 1 1-2
7 2 2
8 2 2
9 2 2
如果您对 2 和 4 也有后缀感到满意,则可以使用稍微简单的解决方案;您可以使用groupby
andcumcount
来生成后缀,然后使用str.cat
来加入它们。
c = (df.groupby('order_id').cumcount() // 3).astype(str)
df['order_id3'] = df['order_id'].astype(str).str.cat(c, sep='-')
df.head(10)
order_id order_id2 order_id3
0 1 1-0 1-0
1 1 1-0 1-0
2 1 1-0 1-0
3 1 1-1 1-1
4 1 1-1 1-1
5 1 1-1 1-1
6 1 1-2 1-2
7 2 2 2-0
8 2 2 2-0
9 2 2 2-0
推荐阅读
- amazon-web-services - 无法从 S3 读取 csv 到 AWS 上 EC2 实例上的 pyspark 数据帧
- java - 单击按钮时 setOnClickListener 没有响应
- python - 用时间计算显示负小时数?
- sql-server - 将 HH:MM:SS 批量转换为秒并更新
- spring-boot - 实体上的 Spring 数据 JPA 自联接。如何指定递归深度?
- javascript - 如何使用 docker-container 运行网络应用程序?
- git - 我尝试使用 git 返回之前的提交,但现在一些 node_modules 无法正常工作。这是为什么?
- arrays - 动态分配字符串数组
- mysql - 对本机函数“JSON_OBJECT”的调用中的参数计数不正确
- ios - 如何解决核心数据崩溃?