Python 计算给定日期的记录数

Python 计算给定日期的记录数,python,sql,pandas,date,count,Python,Sql,Pandas,Date,Count,我曾经有一个SQL查询来计算给定日期、给定位置的记录数 输入数据结构如下: id、位置、开始日期、结束日期 import pandas as pd data = [('20170009003','0681','2017-07-25','2017-08-02'), ('20170009221','0682','2017-07-28','2017-08-02'), ('20170009271','0682','2017-07-31','2017-08-02'), ('20170009286','06

我曾经有一个SQL查询来计算给定日期、给定位置的记录数

输入数据结构如下: id、位置、开始日期、结束日期

import pandas as pd
data = [('20170009003','0681','2017-07-25','2017-08-02'),
('20170009221','0682','2017-07-28','2017-08-02'),
('20170009271','0682','2017-07-31','2017-08-02'),
('20170009286','0681','2017-07-18','2017-09-19'),
('20170009654','0682','2017-07-28','2017-08-03'),
('20170010053','0681','2017-07-31','2017-08-04'),
('20170010059','0681','2017-07-20','2017-08-07')]
labels = ['idnum','loc','start_date','end_date']
df = pd.DataFrame.from_records(data, columns=labels)
这将给我一天(出席)的人数。i、 e.“2018-08-01”将获得:

2018-08-01, 0681, 4
2018-08-01, 0682, 3
我想用python/pandas产生类似的结果

如果有帮助的话,用于实现上述目标的sql(postgreql函数)是:

CREATE OR REPLACE FUNCTION nb_present(oneday date)
 RETURNS TABLE(ddj date, loc character, eff numeric)
 LANGUAGE sql
AS $function$
SELECT $1, loc,sum(case when ($1= start_date and start_date_end_date) then 1 
                when $1=start_date then 0.5 
                when $1=end_date then 0.5 
                when ($1 > start_date and $1 < end_date) then 1 
                else 0 end)
from passage group by 1,2 order by 1,2;
$function$
创建或替换函数nb_当前(一天日期)
返回表(ddj日期、loc字符、eff数字)
语言sql
作为$function$
选择$1、loc、sum(当($1=开始日期和开始日期、结束日期)然后选择1
当$1=开始日期时,则为0.5
当$1=结束日期时,则为0.5
当($1>开始日期和$1<结束日期)时,则1
(完)
从通道组按1,2的顺序依次为1,2;
$function$
谢谢你的帮助


PS:这是我在这里的第一篇帖子。

我相信这就是你要寻找的(确保你的
开始日期和
结束日期都是熊猫
日期时间
对象):

dt=pd.to_datetime('2018-08-01'))
df1=df[(df['startdate']>dt)和(df['enddate']
我相信这就是您要寻找的(确保您的
开始日期
结束日期
是熊猫
日期时间
对象):

dt=pd.to_datetime('2018-08-01'))
df1=df[(df['startdate']>dt)和(df['enddate']
IIUC:

target = '2017-08-01'
df[(df['start_date'] < target) & (df['end_date'] > target)].groupby(['loc']).size()
IIUC:


在你的帮助下,我带来了:

import pandas as pd
data = [('20170009003','0681','2017-07-25','2017-08-02'),
('20170009221','0682','2017-07-28','2017-08-02'),
('20170009271','0682','2017-07-31','2017-08-02'),
('20170009286','0681','2017-07-18','2017-09-19'),
('20170009654','0682','2017-07-28','2017-08-03'),
('20170010053','0681','2017-07-31','2017-08-04'),
('20170010059','0681','2017-07-20','2017-08-07')]
labels = ['idnum','loc','start_date','end_date']
df = pd.DataFrame.from_records(data, columns=labels)
df['end_date'] = pd.to_datetime(df['end_date'])
df['start_date'] = pd.to_datetime(df['start_date'])
dt = pd.to_datetime('2017-08-01')
df1 = df[(df['start_date'] < dt) & (df['end_date'] > dt)].groupby('loc').size().to_frame()
df1['Date'] = dt
将熊猫作为pd导入
数据=[('20170009003'、'0681'、'2017-07-25'、'2017-08-02'),
('20170009221','0682','2017-07-28','2017-08-02'),
('20170009271','0682','2017-07-31','2017-08-02'),
('20170009286','0681','2017-07-18','2017-09-19'),
('20170009654','0682','2017-07-28','2017-08-03'),
('20170010053','0681','2017-07-31','2017-08-04'),
('20170010059','0681','2017-07-20','2017-08-07')]
标签=['idnum'、'loc'、'start_date'、'end_date']
df=pd.DataFrame.from_记录(数据、列=标签)
df['end_date']=pd.to_datetime(df['end_date'])
df['start_date']=pd.to_datetime(df['start_date'])
dt=截止日期时间(2017-08-01)
df1=df[(df['start_date']dt)]。groupby('loc')。size()。to_frame()
df1[“日期”]=dt
这很好用

现在,我必须调整它来计算两个日期之间每天的礼物数量。我会把它作为家庭作业


非常感谢你的帮助,我带来了:

import pandas as pd
data = [('20170009003','0681','2017-07-25','2017-08-02'),
('20170009221','0682','2017-07-28','2017-08-02'),
('20170009271','0682','2017-07-31','2017-08-02'),
('20170009286','0681','2017-07-18','2017-09-19'),
('20170009654','0682','2017-07-28','2017-08-03'),
('20170010053','0681','2017-07-31','2017-08-04'),
('20170010059','0681','2017-07-20','2017-08-07')]
labels = ['idnum','loc','start_date','end_date']
df = pd.DataFrame.from_records(data, columns=labels)
df['end_date'] = pd.to_datetime(df['end_date'])
df['start_date'] = pd.to_datetime(df['start_date'])
dt = pd.to_datetime('2017-08-01')
df1 = df[(df['start_date'] < dt) & (df['end_date'] > dt)].groupby('loc').size().to_frame()
df1['Date'] = dt
将熊猫作为pd导入
数据=[('20170009003'、'0681'、'2017-07-25'、'2017-08-02'),
('20170009221','0682','2017-07-28','2017-08-02'),
('20170009271','0682','2017-07-31','2017-08-02'),
('20170009286','0681','2017-07-18','2017-09-19'),
('20170009654','0682','2017-07-28','2017-08-03'),
('20170010053','0681','2017-07-31','2017-08-04'),
('20170010059','0681','2017-07-20','2017-08-07')]
标签=['idnum'、'loc'、'start_date'、'end_date']
df=pd.DataFrame.from_记录(数据、列=标签)
df['end_date']=pd.to_datetime(df['end_date'])
df['start_date']=pd.to_datetime(df['start_date'])
dt=截止日期时间(2017-08-01)
df1=df[(df['start_date']dt)]。groupby('loc')。size()。to_frame()
df1[“日期”]=dt
这很好用

现在,我必须调整它来计算两个日期之间每天的礼物数量。我会把它作为家庭作业


非常感谢

如果您想在多个日期频繁执行此操作,这里有一个解决方案: 我们创建另一个
DataFrame
,检查该行是否在开始日期和结束日期之间(使用
IntervalIndex
,但不是必需的)。然后,我们可以通过另一个
DataFrame
中的
loc
变量对
DataFrame
进行分组(分组是在索引上对齐的,因此我们使用
.reset_index
来确保所有内容都与我们新创建的
DataFrame
对齐),并且只取一个和,因为我们有
True
False

import pandas as pd
import numpy as np

df['start_date'] = pd.to_datetime(df.start_date)
df['end_date'] = pd.to_datetime(df.end_date)
df.index = pd.IntervalIndex.from_arrays(df.start_date, df.end_date, closed='both')

# Dates you care about
dates = pd.to_datetime(['2017-08-01', '2017-08-02', '2017-08-03'])

df_bet = pd.DataFrame(np.reshape([d in ids for d in dates for ids in df.index] ,(-1, len(df))), index=dates).T

df_bet.groupby(df.reset_index()['loc']).agg(sum)
输出:
如果您想在多个日期频繁执行此操作,这里有一个解决方案: 我们创建另一个
DataFrame
,检查该行是否在开始日期和结束日期之间(使用
IntervalIndex
,但不是必需的)。然后,我们可以通过另一个
DataFrame
中的
loc
变量对
DataFrame
进行分组(分组是在索引上对齐的,因此我们使用
.reset_index
来确保所有内容都与我们新创建的
DataFrame
对齐),并且只取一个和,因为我们有
True
False

import pandas as pd
import numpy as np

df['start_date'] = pd.to_datetime(df.start_date)
df['end_date'] = pd.to_datetime(df.end_date)
df.index = pd.IntervalIndex.from_arrays(df.start_date, df.end_date, closed='both')

# Dates you care about
dates = pd.to_datetime(['2017-08-01', '2017-08-02', '2017-08-03'])

df_bet = pd.DataFrame(np.reshape([d in ids for d in dates for ids in df.index] ,(-1, len(df))), index=dates).T

df_bet.groupby(df.reset_index()['loc']).agg(sum)
输出:
仅使用python就可以做到这一点,使用带有两个元素的sorted和带有两个元素的groupby

from itertools import groupby
from operator import itemgetter

data = sorted(data, key= itemgetter(-1, 1))
for k, g in groupby(data, key = itemgetter(-1, 1)):
    print('{}, {}, {}'.format(k[0], k[1], len(list(g))))

仅使用python就可以做到这一点,使用带有两个元素的sorted和带有两个元素的groupby

from itertools import groupby
from operator import itemgetter

data = sorted(data, key= itemgetter(-1, 1))
for k, g in groupby(data, key = itemgetter(-1, 1)):
    print('{}, {}, {}'.format(k[0], k[1], len(list(g))))

我终于想出了一个稍微不同的解决办法。当我需要将结果数据帧与另一个数据帧合并时,下面是我所做的:

df0 = pd.DataFrame()
for dt in pd.date_range('2017-08-01', '2017-08-05'):
    df1 = df[(df['start_date'] < dt) & (df['end_date'] > dt)].groupby('loc').size().to_frame().reset_index()
    df1['Date'] = dt
    df0 = df0.append(df1)
df0=pd.DataFrame()
对于pd日期范围内的dt(“2017-08-01”、“2017-08-05”):
df1=df[(df['start_date']dt)].groupby('loc').size().to_frame().reset_index()
df1[“日期”]=dt
df0=df0.append(df1)

最诚挚的问候

我终于想出了一个稍微不同的解决方案。当我需要将结果数据帧与另一个数据帧合并时,下面是我所做的:

df0 = pd.DataFrame()
for dt in pd.date_range('2017-08-01', '2017-08-05'):
    df1 = df[(df['start_date'] < dt) & (df['end_date'] > dt)].groupby('loc').size().to_frame().reset_index()
    df1['Date'] = dt
    df0 = df0.append(df1)
df0=pd.DataFrame()
对于pd日期范围内的dt(“2017-08-01”、“2017-08-05”):
df1=df[(df['start_date']dt)].groupby('loc').size().to_frame().reset_index()
df1[“日期”]=dt
df0=df0.append(df1)

致以最诚挚的问候

到目前为止,您尝试了什么?顺便说一句,你的英语很好。无需担心:-)您能以不同的格式提供示例数据吗?例如,没有垂直线//给定日期的出席人数,即“2018-08-01”//您确定您的意思是
2018-08-01吗