计算 Pandas Dataframe 中两个日期之间的 GroupBy 内的行数

2023-12-06

我有一个数据框df,可以使用以下代码创建:

import random
from datetime import timedelta
import pandas as pd
import datetime

#create test range of dates
rng=pd.date_range(datetime.date(2015,7,15),datetime.date(2015,7,31))
rnglist=rng.tolist()
testpts = range(100,121)
#create test dataframe
d={'jid':[i for i in range(100,121)], 
   'cid':[random.randint(1,2) for _ in testpts],
   'ctid':[random.randint(3,4) for _ in testpts],       
    'stdt':[rnglist[random.randint(0,len(rng))] for _ in testpts]}
df=pd.DataFrame(d)[['jid','cid','ctid','stdt']]
df['enddt'] = df['stdt']+timedelta(days=random.randint(2,16))

The df看起来像这样:

      jid  cid  ctid       stdt      enddt
0   100    1     4 2015-07-28 2015-08-11
1   101    2     3 2015-07-31 2015-08-14
2   102    2     3 2015-07-31 2015-08-14
3   103    1     3 2015-07-24 2015-08-07
4   104    2     4 2015-07-27 2015-08-10
5   105    1     4 2015-07-27 2015-08-10
6   106    2     4 2015-07-24 2015-08-07
7   107    2     3 2015-07-22 2015-08-05
8   108    2     3 2015-07-28 2015-08-11
9   109    1     4 2015-07-20 2015-08-03
10  110    2     3 2015-07-29 2015-08-12
11  111    1     3 2015-07-29 2015-08-12
12  112    1     3 2015-07-27 2015-08-10
13  113    1     3 2015-07-21 2015-08-04
14  114    1     4 2015-07-28 2015-08-11
15  115    2     3 2015-07-28 2015-08-11
16  116    1     3 2015-07-26 2015-08-09
17  117    1     3 2015-07-25 2015-08-08
18  118    2     3 2015-07-26 2015-08-09
19  119    2     3 2015-07-19 2015-08-02
20  120    2     3 2015-07-22 2015-08-05

我需要做的是:计数(cnt) 的数量jid发生的ctid by cid,对于每个日期(newdate) 在。。之间min(stdt) and max(enddt),其中newdate是介于stdtenddt.

生成的 DataFrame 应该看起来像(这仅适用于 1cid with 1 ctid使用上述数据)(在这种情况下这将复制cid 1/ctid 4, cid 2/ctid 3, cid 2/ctid 4):

cid ctid    newdate cnt
1   3   7/21/2015   1
1   3   7/22/2015   1
1   3   7/23/2015   1
1   3   7/24/2015   2
1   3   7/25/2015   3
1   3   7/26/2015   4
1   3   7/27/2015   5
1   3   7/28/2015   5
1   3   7/29/2015   6
1   3   7/30/2015   6
1   3   7/31/2015   6
1   3   8/1/2015    6
1   3   8/2/2015    6
1   3   8/3/2015    6
1   3   8/4/2015    6
1   3   8/5/2015    5
1   3   8/6/2015    5
1   3   8/7/2015    5
1   3   8/8/2015    4
1   3   8/9/2015    3
1   3   8/10/2015   2
1   3   8/11/2015   1
1   3   8/12/2015   1

上一个问题(也是我的)计算日期之间的行数,非常相似,并使用pd.melt。我很确定melt可以再次使用,或者也许有更好的选择,但我不知道如何完成“两层分组”,它计算的大小jid对于每个ctid,对于每个cid,对于每个newdate。喜欢你的投入...


在尝试@Scott Boston 答案后,对于 1.8m 记录 df,第一行

df_out = pd.concat([pd.DataFrame(index=pd.date_range(df.iloc[i].stdt,df.iloc[i].enddt)).assign(**df.iloc[i,0:3]) for i in pd.np.arange(df.shape[0])]).reset_index()

1小时后仍在运行,并慢慢侵蚀记忆。所以我想我会尝试以下操作:

def reindex_by_date(df):
    dates = pd.date_range(df.index.min(), df.index.max())
    return df.reindex(dates)
def replace_last_0(group):
    group.loc[max(group.index),'change']=0
    return group

def ctidloop(partdf): 
        coid=partdf.cid.max()
        cols=['cid', 'stdt', 'enddt']
        partdf=partdf[cols]
        partdf['jid']=partdf.index
        partdf = pd.melt(partdf, id_vars=['ctid', 'jid'],var_name='change', value_name='newdate')
        partdf['change'] = partdf['change'].replace({'stdt': 1, 'enddt': -1})
        partdf.newdate=pd.DatetimeIndex(partdf['newdate'])
        partdf=partdf.groupby(['ctid', 'newdate'],as_index=False)['change'].sum()
        partdf=partdf.groupby('ctid').apply(replace_last_0).reset_index(drop=True)
        partdf['cnt'] = partdf.groupby('ctid')['change'].cumsum()
        partdf.index=partdf['newdate']
        cols=['ctid', 'change', 'cnt', 'newdate']
        partdf=partdf[cols]
        partdf=partdf.groupby('ctid').apply(reindex_by_date).reset_index(0, drop=True)
        partdf['newdate']=partdf.index
        partdf['ctid']=partdf['ctid'].fillna(method='ffill')
        partdf.cnt=partdf.cnt.fillna(method='ffill')
        partdf.change=partdf.change.fillna(0)
        partdf['cid']=coid
        return partdf
gb=df.groupby('cid').apply(ctidloop)

此代码返回正确的结果:

%timeit gb=df.groupby('cid').apply(ctidloop)
1 loop, best of 3: 9.74 s per loop 

解释: 基本上,melt非常快。所以我想打破第一个groupby分组并对其运行函数。所以这段代码采用df, then groupsby the cid and apply功能cidloop.

In the cidloop,按行发生以下情况: 1)抓住cid以供将来使用。 2,3)建立核心partdf通过分配所需的列进行处理 4)创建jid从索引 5)运行pd.melt它通过为每个数据框创建一行来展平数据框jid for stdt and enddt。 6)创建一个'change'将+1分配给的列stdt,和 -1 到enddt。 7) 使newdate a datetimeindex(只是更容易进一步处理) 8)对我们所拥有的进行分组ctid and newdate,总结change9) 分组依据ctid再次,用 0 替换最后一个值(这只是我需要的,而不是特定于问题的) 10) 创造cnt按组按ctid and cumsumming改变 11) 生成新的索引newdate12,13)​​ 格式化列/名称 14) 另一个groupbyctid但按高日期和低日期重新索引,填补空白。 15) 分配newdate从新的reindex价值观 16,17,18)填充各种值以填补空白(我需要此增强功能) 19) 分配cid再次从顶部变量coid聚集在1号线。

对每个都执行此操作cid通过最后一行代码gb=df.groupby.....

感谢@Scott Boston 的尝试。当然它有效,但对我来说花了太长时间。

感谢@DSM 的解决方案HERE这是我解决方案的基础。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算 Pandas Dataframe 中两个日期之间的 GroupBy 内的行数 的相关文章

  • 将 numpy 数组合并为单个 int

    numpy 数组怎么可以这样 10 22 37 45 转换为单个 int32 数字 如下所示 10223745 这可以工作 gt gt gt int join map str 10 22 37 45 10223745 基本上你使用map s
  • 反编译Python 3.9.2的PYC文件[重复]

    这个问题在这里已经有答案了 目前 我有一个 3 9 2 版本的 python 的 PYC 文件 P S 这适用于所有 3 9 及更高版本 我正在尝试反编译 PYC 文件 但它显示错误 因为 uncompyle6 或者更确切地说 新版本 de
  • 按边距(“全部”)值列对 Pandas 数据透视表进行排序

    我试图根据 pandas 数据透视表中的行总和对最后一列 边距 aggrfunc 进行降序排序 我知道我在这里错过了一些简单的东西 但我无法弄清楚 数据框 数据透视表 WIDGETS DATE 2 1 16 2 2 16 2 3 16 Al
  • 从 Azure ML 实验中访问 Azure Blob 存储

    Azure ML 实验提供了通过以下方式读取 CSV 文件并将其写入 Azure Blob 存储的方法 Reader and Writer模块 但是 我需要将 JSON 文件写入 blob 存储 由于没有模块可以执行此操作 因此我尝试在Ex
  • Series.sort() 和 Series.order() 有什么区别?

    s pd Series nr randint 0 10 5 index nr randint 0 10 5 s Output 1 3 7 6 2 0 9 7 1 6 order 按值排序并返回一个新系列 s order Output 2 0
  • 创建上下文后将 jar 文件添加到 pyspark

    我正在笔记本上使用 pyspark 并且不处理 SparkSession 的创建 我需要加载一个包含一些我想在处理 rdd 时使用的函数的 jar 您可以使用 jars 轻松完成此操作 但在我的特定情况下我无法做到这一点 有没有办法访问sp
  • 协程从未被等待

    我正在使用一个简单的上下文管理器 其中包含一个异步循环 class Runner def init self self loop asyncio get event loop def enter self return self def e
  • 使用python从gst管道抓取帧到opencv

    我在用着OpenCV http opencv org 和GStreamer0 10 我使用此管道通过自定义套接字通过 UDP 接收 MPEG ts 数据包sockfd由 python 提供并显示它xvimagesink 而且效果很好 以下命
  • Arcpy 模数在 Pycharm 中不显示

    如何将 Arcpy 集成到 Pycharm 中 我尝试通过导入模块但它没有显示 我确实知道该模块仅适用于 2 x python arcpy 在 PyPi Python 包索引 上不可用 因此无法通过 pip 安装 要使用 arcpy 您需要
  • Python将文本文件解析为嵌套字典

    考虑以下数据结构 HEADER1 key value key value HEADER2 key value key value HEADER3 key value HEADER4 key value key value 原始数据中没有缩进
  • 使用 for 循环创建一系列元组

    我已经搜索过 但找不到答案 尽管我确信它已经存在了 我对 python 很陌生 但我以前用其他语言做过这种事情 我正在以行形式读取数据文件 我想将每行数据存储在它自己的元组中 以便在 for 循环之外访问 tup i inLine wher
  • 使用 Python 将连续日期分组在一起

    Given dates datetime 2014 10 11 datetime 2014 10 1 datetime 2014 10 2 datetime 2014 10 3 datetime 2014 10 5 datetime 201
  • 在Raspberry pi上升级skimage版本

    我已经使用 Raspberry Pi 2 上的 synaptic 包管理器安装了 python 包 然而 skimage 模块版本 0 6 是 synaptic 中最新的可用版本 有人可以指导我如何将其升级到0 11 因为旧版本中缺少某些功
  • 如何指示 urwid 列表框的项目数多于当前显示的项目数?

    有没有办法向用户显示 urwid 列表框在显示部分上方 下方有其他项目 我正在考虑类似滚动条的东西 它可以显示条目的数量 或者列表框顶部 底部的单独栏 如果这个行为无法实现 有哪些方法可以实现这个通知 在我的研究过程中 我发现这个问题 ht
  • 无法通过 Python 子进程进行 SSH

    我需要通过堡垒 ssh 进入机器 因此 该命令相当长 ssh i
  • AWS Lambda 不读取环境变量

    我正在编写一个 python 脚本来查询 Qualys API 中的漏洞元数据 我在 AWS 中将其作为 lambda 函数执行 我已经在控制台中设置了环境变量 但是当我执行函数时 出现以下错误 module initialization
  • 如何将带有参数的Python装饰器实现为类?

    我正在尝试实现一个接受一些参数的装饰器 通常带有参数的装饰器被实现为双重嵌套闭包 如下所示 def mydecorator param1 param2 do something with params def wrapper fn def
  • rpy2 无法加载外部库

    希望有人能帮忙解决这个问题 R版本 2 14 1rpy2版本 2 2 5蟒蛇版本 2 7 3 一直在尝试在 python 脚本中使用 rpy2 加载 R venneuler 包 该包以 rJava 作为依赖项 venneuler 和 rJa
  • 如何从namedtuple实例列表创建pandas DataFrame(带有索引或多索引)?

    简单的例子 from collections import namedtuple import pandas Price namedtuple Price ticker date price a Price GE 2010 01 01 30
  • pandas 中数据帧中的随机/洗牌行

    我目前正在尝试找到一种方法来按行随机化数据框中的项目 我在 pandas 中按列洗牌 排列找到了这个线程 在 pandas 中对 DataFrame 进行改组 排列 https stackoverflow com questions 157

随机推荐