Python Pandas 日期时间范围之间的累积列
Python Pandas cumulative column between datetime ranges
我正在尝试使用 pandas 数据透视表 table 在任意两个给定日期时间范围之间生成一个累积列,但目前尚不清楚如何实际实现这一点。我可以按照以下为所有日期创建一个。
所有日期时间:
sum count cum_sum
dt
2015-01-01 10:00:00 10 10
2015-01-01 12:00:00 20 30
2015-01-01 13:00:00 30 60
2015-01-02 10:00:00 10 70
2015-01-02 12:00:00 20 90
2015-01-02 13:00:00 30 120
在两个指定的日期时间之间:
sum count cum_sum
dt
2015-01-01 12:00:00 20 30
2015-01-01 13:00:00 30 60
2015-01-02 10:00:00 10 70
2015-01-02 12:00:00 20 90
有没有办法生成上面的 table,但是从查询中的开始日期开始累积(或者在数据帧本身中这样做?)。
我的代码:
import pandas as pd
import numpy as np
from datetime import datetime
data=[
{'count': 10, 'dt': datetime.strptime("20150101 10:00", "%Y%m%d %H:%M") },
{'count': 20, 'dt': datetime.strptime("20150101 12:00", "%Y%m%d %H:%M") },
{'count': 30, 'dt': datetime.strptime("20150101 13:00", "%Y%m%d %H:%M") },
{'count': 10, 'dt': datetime.strptime("20150102 10:00", "%Y%m%d %H:%M") },
{'count': 20, 'dt': datetime.strptime("20150102 12:00", "%Y%m%d %H:%M") },
{'count': 30, 'dt': datetime.strptime("20150102 13:00", "%Y%m%d %H:%M") }
]
df = pd.DataFrame(data)
df['cum_sum']=df['count'].cumsum()
pivot=pd.pivot_table(df, index=['dt'],aggfunc=[np.sum])
print (pivot)
result = pivot.query('dt >= "{0}" and dt <=" {1}"'.format(
datetime.strptime("20150101 11:00", "%Y%m%d %H:%M"),
datetime.strptime("20150102 12:00", "%Y%m%d %H:%M")
))
print (result)
编辑:我想在 2 个日期范围之间创建一个累积列,但有子标准。
data=[
{'loc': 'Japan', 'count': 10, 'dt': datetime.strptime("20150101 10:00", "%Y%m%d %H:%M") },
{'loc': 'Japan', 'count': 20, 'dt': datetime.strptime("20150101 12:00", "%Y%m%d %H:%M") },
{'loc': 'Japan', 'count': 30, 'dt': datetime.strptime("20150101 13:00", "%Y%m%d %H:%M") },
{'loc': 'London', 'count': 10, 'dt': datetime.strptime("20150102 10:00", "%Y%m%d %H:%M") },
{'loc': 'London', 'count': 20, 'dt': datetime.strptime("20150102 12:00", "%Y%m%d %H:%M") },
{'loc': 'NewYork', 'count': 30, 'dt': datetime.strptime("20150102 13:00", "%Y%m%d %H:%M") }
]
所以输出将针对特定的日期时间范围:
Loc Count cum_sum
Japan
2015-01-01 10:00:00 10 10
2015-01-01 13:00:00 30 40
2015-01-02 13:00:00 30 70
London
2015-01-01 12:00:00 20 20
2015-01-02 10:00:00 10 20
2015-01-02 12:00:00 20 40
下面是一个简单但不是很复杂的处理方法:
df = pd.DataFrame(data)
df.set_index('dt', inplace=True)
df['cumsum'] = df['count']
df.loc[df.index < datetime.strptime("20150101 11:00", "%Y%m%d %H:%M"), 'cumsum'] = 0.0
df['cumsum'] = df['cumsum'].cumsum()
print(df)
给出以下结果:
count cumsum
dt
2015-01-01 10:00:00 10 0
2015-01-01 12:00:00 20 20
2015-01-01 13:00:00 30 50
2015-01-02 10:00:00 10 60
2015-01-02 12:00:00 20 80
2015-01-02 13:00:00 30 110
您可以使用日期时间列重新定义 Dataframe 的索引并使用 .ix
,例如 this:
df.index = df.dt
time1=datetime.strptime("20150101 11:00", "%Y%m%d %H:%M")
time2=datetime.strptime("20150102 12:00", "%Y%m%d %H:%M")
df.ix[time1:time2]['count'].cumsum()
如果您想包括第一天的所有值,您可以使用 time1
日期时间对象的 date()
函数:
df.ix[time1.date():time2]['count'].cumsum()
给出:
2015-01-01 10:00:00 10
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
2015-01-02 10:00:00 70
2015-01-02 12:00:00 90
Name: count, dtype: int64
要获得您要求的输出,从 time1
开始,您可以添加 [time1:]
:
df.ix[time1.date():time2]['count'].cumsum()[time1:]
给予:
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
2015-01-02 10:00:00 70
2015-01-02 12:00:00 90
Name: count, dtype: int64
编辑
在回答您的后续问题时,您可以使用 groupby(取自 this answer):
df.index=df.dt
df=df.ix[time1.date():time2]['count'].reset_index() # filter times and remove date index
df.groupby(by=['loc','dt']).sum().groupby(level=[0]).cumsum()
给出:
count
loc dt
Japan 2015-01-01 10:00:00 10
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
London 2015-01-02 10:00:00 10
2015-01-02 12:00:00 30
NewYork 2015-01-02 13:00:00 30
我正在尝试使用 pandas 数据透视表 table 在任意两个给定日期时间范围之间生成一个累积列,但目前尚不清楚如何实际实现这一点。我可以按照以下为所有日期创建一个。
所有日期时间:
sum count cum_sum
dt
2015-01-01 10:00:00 10 10
2015-01-01 12:00:00 20 30
2015-01-01 13:00:00 30 60
2015-01-02 10:00:00 10 70
2015-01-02 12:00:00 20 90
2015-01-02 13:00:00 30 120
在两个指定的日期时间之间:
sum count cum_sum
dt
2015-01-01 12:00:00 20 30
2015-01-01 13:00:00 30 60
2015-01-02 10:00:00 10 70
2015-01-02 12:00:00 20 90
有没有办法生成上面的 table,但是从查询中的开始日期开始累积(或者在数据帧本身中这样做?)。
我的代码:
import pandas as pd
import numpy as np
from datetime import datetime
data=[
{'count': 10, 'dt': datetime.strptime("20150101 10:00", "%Y%m%d %H:%M") },
{'count': 20, 'dt': datetime.strptime("20150101 12:00", "%Y%m%d %H:%M") },
{'count': 30, 'dt': datetime.strptime("20150101 13:00", "%Y%m%d %H:%M") },
{'count': 10, 'dt': datetime.strptime("20150102 10:00", "%Y%m%d %H:%M") },
{'count': 20, 'dt': datetime.strptime("20150102 12:00", "%Y%m%d %H:%M") },
{'count': 30, 'dt': datetime.strptime("20150102 13:00", "%Y%m%d %H:%M") }
]
df = pd.DataFrame(data)
df['cum_sum']=df['count'].cumsum()
pivot=pd.pivot_table(df, index=['dt'],aggfunc=[np.sum])
print (pivot)
result = pivot.query('dt >= "{0}" and dt <=" {1}"'.format(
datetime.strptime("20150101 11:00", "%Y%m%d %H:%M"),
datetime.strptime("20150102 12:00", "%Y%m%d %H:%M")
))
print (result)
编辑:我想在 2 个日期范围之间创建一个累积列,但有子标准。
data=[
{'loc': 'Japan', 'count': 10, 'dt': datetime.strptime("20150101 10:00", "%Y%m%d %H:%M") },
{'loc': 'Japan', 'count': 20, 'dt': datetime.strptime("20150101 12:00", "%Y%m%d %H:%M") },
{'loc': 'Japan', 'count': 30, 'dt': datetime.strptime("20150101 13:00", "%Y%m%d %H:%M") },
{'loc': 'London', 'count': 10, 'dt': datetime.strptime("20150102 10:00", "%Y%m%d %H:%M") },
{'loc': 'London', 'count': 20, 'dt': datetime.strptime("20150102 12:00", "%Y%m%d %H:%M") },
{'loc': 'NewYork', 'count': 30, 'dt': datetime.strptime("20150102 13:00", "%Y%m%d %H:%M") }
]
所以输出将针对特定的日期时间范围:
Loc Count cum_sum
Japan
2015-01-01 10:00:00 10 10
2015-01-01 13:00:00 30 40
2015-01-02 13:00:00 30 70
London
2015-01-01 12:00:00 20 20
2015-01-02 10:00:00 10 20
2015-01-02 12:00:00 20 40
下面是一个简单但不是很复杂的处理方法:
df = pd.DataFrame(data)
df.set_index('dt', inplace=True)
df['cumsum'] = df['count']
df.loc[df.index < datetime.strptime("20150101 11:00", "%Y%m%d %H:%M"), 'cumsum'] = 0.0
df['cumsum'] = df['cumsum'].cumsum()
print(df)
给出以下结果:
count cumsum
dt
2015-01-01 10:00:00 10 0
2015-01-01 12:00:00 20 20
2015-01-01 13:00:00 30 50
2015-01-02 10:00:00 10 60
2015-01-02 12:00:00 20 80
2015-01-02 13:00:00 30 110
您可以使用日期时间列重新定义 Dataframe 的索引并使用 .ix
,例如 this:
df.index = df.dt
time1=datetime.strptime("20150101 11:00", "%Y%m%d %H:%M")
time2=datetime.strptime("20150102 12:00", "%Y%m%d %H:%M")
df.ix[time1:time2]['count'].cumsum()
如果您想包括第一天的所有值,您可以使用 time1
日期时间对象的 date()
函数:
df.ix[time1.date():time2]['count'].cumsum()
给出:
2015-01-01 10:00:00 10
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
2015-01-02 10:00:00 70
2015-01-02 12:00:00 90
Name: count, dtype: int64
要获得您要求的输出,从 time1
开始,您可以添加 [time1:]
:
df.ix[time1.date():time2]['count'].cumsum()[time1:]
给予:
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
2015-01-02 10:00:00 70
2015-01-02 12:00:00 90
Name: count, dtype: int64
编辑
在回答您的后续问题时,您可以使用 groupby(取自 this answer):
df.index=df.dt
df=df.ix[time1.date():time2]['count'].reset_index() # filter times and remove date index
df.groupby(by=['loc','dt']).sum().groupby(level=[0]).cumsum()
给出:
count
loc dt
Japan 2015-01-01 10:00:00 10
2015-01-01 12:00:00 30
2015-01-01 13:00:00 60
London 2015-01-02 10:00:00 10
2015-01-02 12:00:00 30
NewYork 2015-01-02 13:00:00 30