我有一个数据框,其中包含多个实体随时间的观察结果。索引是一个时间序列,是唯一的,但不规则。
数据框的一部分如下所示:
DATE ('ACTION', 111, 1/7/2010) ('ACTION', 222, 1/5/2010)
1/1/2010 10 5
1/2/2010 10 5
1/3/2010 10 5
1/4/2010 15 5
1/5/2010 10 5
1/6/2010 10 5
1/7/2010 10 5
1/8/2010 10 5
元组是一个分层索引。在元组值1中是类别,值2是ID,值3是事件日期。我想将此事件日期用作列中的最大日期-1,并将该日期之后的值替换为NaN
新框架如下所示:
DATE ('ACTION', 111, 1/7/2010) ('ACTION', 222, 1/5/2010)
1/1/2010 10 5
1/2/2010 10 5
1/3/2010 10 5
1/4/2010 15 5
1/5/2010 10 NaN
1/6/2010 10 NaN
1/7/2010 NaN NaN
1/8/2010 NaN NaN
数据框可能包含100000列。我理解如何使用布尔掩码替换值是一列我认为。我不明白如何在多列上有效地执行此操作。
需要这样做的原因是为了确保观察发生在事件发生日期的个别事件之前。任何帮助都将受到高度赞赏。
答案 0 :(得分:2)
也许也不是那么快,但已经基于熊猫的清洁方法了:
df.where(df.apply(lambda x: x.index < pd.Timestamp(x.name[2])))
apply
返回一个具有True / False值的数据框(<
表达式针对x.name[2]
选择该列名的第三级的每一列进行评估),以及替换的位置NaN的假值。
完整示例:
In [1]: import pandas as pd
In [2]: from StringIO import StringIO
In [3]: s = """,ACTION,ACTION
...: ,111,222
...: ,1/7/2010,1/5/2010
...: DATE,,
...: 1/1/2010, 10, 5
...: 1/2/2010, 10, 5
...: 1/3/2010, 10, 5
...: 1/4/2010, 15, 5
...: 1/5/2010, 10, 5
...: 1/6/2010, 10, 5
...: 1/7/2010, 10, 5
...: 1/8/2010, 10, 5"""
In [4]: df = pd.read_csv(StringIO(s), header=[0,1,2], index_col=0, parse_dates=True)
In [5]: df.where(df.apply(lambda x: x.index < pd.Timestamp(x.name[2])))
Out[5]:
ACTION
111 222
1/7/2010 1/5/2010
DATE
2010-01-01 10 5
2010-01-02 10 5
2010-01-03 10 5
2010-01-04 15 5
2010-01-05 10 NaN
2010-01-06 10 NaN
2010-01-07 NaN NaN
2010-01-08 NaN NaN
答案 1 :(得分:1)
我相信可能有更好的方法可以做到这一点,但是有三行可以完成这项工作
In [194]:
A=(np.array(pd.to_datetime(df['DATE']))[...,np.newaxis]+12*60*12*10**10)>\
np.array([np.datetime64(pd.to_datetime(item[-1])) for item in df.columns.tolist()[1:]])
B=np.hstack((np.ones(len(df)).reshape((-1,1))!=1, A))
print df.where(~B)
# DATE (ACTION, 111, 1/7/2010) (ACTION, 222, 1/5/2010)
#0 1/1/2010 10 5
#1 1/2/2010 10 5
#2 1/3/2010 10 5
#3 1/4/2010 15 5
#4 1/5/2010 10 NaN
#5 1/6/2010 10 NaN
#6 1/7/2010 NaN NaN
#7 1/8/2010 NaN NaN
#[8 rows x 3 columns]
我认为您的DATE
列存储为string
,列名中每个元组的最后一项也存储在string
中。如果两者都是这种情况,您将需要第一行中的转换,否则您可以跳过一些。
编辑:运行速度慢,100 loops, best of 3: 4.55 ms per loop
。