Python 在数据帧中搜索
可能是一个有点误导性的标题,但问题是: 我有一个包含多个列的大型数据框。这看起来有点像Python 在数据帧中搜索,python,pandas,Python,Pandas,可能是一个有点误导性的标题,但问题是: 我有一个包含多个列的大型数据框。这看起来有点像 df = id date value A 01-01-2015 1.0 A 03-01-2015 1.2 ... B 01-01-2015 0.8 B 02-01-2015 0.8 ... 我想做的是,在每个ID中,我提前一周确定日期,并将该日期的值放入例如“lagvalue”列中。问题在于并非所有ID的所有日期都存在,因此简单的.sh
df =
id date value
A 01-01-2015 1.0
A 03-01-2015 1.2
...
B 01-01-2015 0.8
B 02-01-2015 0.8
...
我想做的是,在每个ID中,我提前一周确定日期,并将该日期的值放入例如“lagvalue”列中。问题在于并非所有ID的所有日期都存在,因此简单的.shift(7)不会提取正确的值[在本例中,我想我应该在中添加一个NaN]
我可以通过对日期和ID进行大量可怕的迭代来找到值,例如一些粗略的想法
[
df[
df['date'] == df['date'].iloc[i] - datetime.timedelta(weeks=1)
][
df['id'] == df['id'].iloc[i]
]['value']
for i in range(len(df.index))
]
但我确信有一种“更好”的方法可以减少时间和处理,这是我现在想不到的
我可以在id上使用groupby编写一个函数,然后查看其中的内容,我确信这将减少执行操作所需的时间-是否有一种更快速、更简单的方法[也就是说,我有一个暗淡的一天]?对于每个id,基本策略是:
- 使用日期索引
- 使用
展开数据以包括所有日期reindex
- 使用
移动7个点shift
- 使用
进行最后一次值插值。我不确定您是否想要这个,或者可能是ffill
,它将使用过去不到一周的最后一个值。但改变很简单。或者,如果您想在过去7天不可用时使用NaN,您可以完全删除bfill
*填充
- 删除不需要的数据
NaN
这里有一些假设。特别是,每个id中的日期都是唯一的,并且它们是经过排序的。如果未排序,则使用排序\u值
按id和日期排序。如果存在重复的日期,则需要一些规则来解析要使用的值
import pandas as pd
import numpy as np
dates = pd.date_range('2001-01-01',periods=100)
dates = dates[::3]
A = pd.DataFrame({'date':dates,
'id':['A']*len(dates),
'value':np.random.randn(len(dates))})
dates = pd.date_range('2001-01-01',periods=100)
dates = dates[::5]
B = pd.DataFrame({'date':dates,
'id':['B']*len(dates),
'value':np.random.randn(len(dates))})
df = pd.concat([A,B])
with_lags = []
for id, group in df.groupby('id'):
group = group.set_index(group.date)
index = group.index
group = group.reindex(pd.date_range(group.index[0],group.index[-1]))
group = group.ffill()
group['lag_value'] = group.value.shift(7)
group = group.loc[index]
with_lags.append(group)
with_lags = pd.concat(with_lags, 0)
with_lags.index = np.arange(with_lags.shape[0])
好问题,但我想我遗漏了一点:你想用每个ID标识比一个特定记录早一周的日期吗?如果是这样,您如何选择每个ID的记录中应该包含哪些?还是别的什么?(可以理解的是,我不太明白你基于迭代的解决方案在做什么…尽管还在努力)@DavidZ对于每个日期[因此对于数据帧每行的id aka中的每个日期]我想提前一周确定日期,并且如果该日期上该项有关联的值,则将其放入新列中。这更有意义吗?我想是的。让我看看我是否能想出什么办法。也许我没有正确理解你的问题,但是没有
df['lagvalue']=df['date']-datetime.timedelta(weeks=1)
做这个把戏?@durrutti我不想要日期,我想要值列中的值,其中日期与前一周的日期匹配。如果我有所有可能的日期,那么“值”上的.shift(+7)将是我想要的。