我有有关机器故障的数据。数据位于具有date
,id
,failure
和previous_30_days
列的熊猫数据框中。 previous_30_days
列当前为全零。我希望得到的结果是,如果在故障发生前30天的时间跨度内出现在previous_30_days
列中的行为“ 1”。我目前可以使用以下代码执行此操作:
failure_df = df[(df['failure'] == 1)] # create a dataframe of just failures
for index, row in failure_df.iterrows():
df.loc[(df['date'] >= (row.date - datetime.timedelta(days=30))) &
(df['date'] <= row.date) & (df['id'] == row.id), 'previous_30_days'] = 1
请注意,我还要检查id是否匹配,因为日期在数据帧中重复,因此我不能认为它只是前30行。
我的代码可以运行,但是问题是数据帧是数百万行,并且此代码目前太慢。
有没有更有效的方法来达到预期的结果?任何想法将不胜感激。
最佳答案
对于您的代码如何工作(或应该工作),我有些困惑,但这应该为您指明正确的方向,并且可以轻松地进行调整。通过避免使用iterrows
来支持矢量化操作,它将更快(对于此小型数据帧,速度大约快7倍,这对大型数据帧而言应该是更大的改进)。
np.random.seed(123)
df=pd.DataFrame({ 'date':np.random.choice(pd.date_range('2015-1-1',periods=300),20),
'id':np.random.randint(1,4,20) })
df=df.sort(['id','date'])
现在,计算当前日期和上一个日期之间的天数(按ID)。
df['since_last'] = df.groupby('id')['date'].apply( lambda x: x - x.shift() )
然后根据上一个日期的天数创建新列。
df['previous_30_days'] = df['since_last'] < datetime.timedelta(days=30)
date id since_last previous_30_days
12 2015-02-17 1 NaT False
6 2015-02-27 1 10 days True
3 2015-03-25 1 26 days True
0 2015-04-09 1 15 days True
10 2015-04-24 1 15 days True
5 2015-05-04 1 10 days True
11 2015-05-07 1 3 days True
8 2015-08-14 1 99 days False
14 2015-02-02 2 NaT False
9 2015-04-07 2 64 days False
19 2015-07-28 2 112 days False
7 2015-08-03 2 6 days True
15 2015-08-13 2 10 days True
1 2015-08-19 2 6 days True
2 2015-01-18 3 NaT False
13 2015-03-15 3 56 days False
18 2015-04-07 3 23 days True
4 2015-04-17 3 10 days True
16 2015-04-22 3 5 days True
17 2015-09-11 3 142 days False
关于python - Python(Pandas)在指定条件下更新前x行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31701732/