【发布时间】:2017-09-26 06:30:31
【问题描述】:
这是对我之前的问题here 的跟进。 假设这样的数据集(最初是从 .csv 读取的):
data = pd.DataFrame({'id': [1,2,3,1,2,3,1,2,3],
'time':['2017-01-01 12:00:00','2017-01-01 12:00:00','2017-01-01 12:00:00',
'2017-01-01 12:10:00','2017-01-01 12:10:00','2017-01-01 12:10:00',
'2017-01-01 12:20:00','2017-01-01 12:20:00','2017-01-01 12:20:00'],
'values': [10,11,12,10,12,13,10,13,13]})
data = data.set_index('id')
=>
id time values
0 1 2017-01-01 12:00:00 10
1 2 2017-01-01 12:00:00 11
2 3 2017-01-01 12:00:00 12
3 1 2017-01-01 12:10:00 10
4 2 2017-01-01 12:10:00 12
5 3 2017-01-01 12:10:00 13
6 1 2017-01-01 12:20:00 10
7 2 2017-01-01 12:20:00 13
8 3 2017-01-01 12:20:00 13
每个观察期内所有 ID 的时间都相同。该系列以这样的方式进行许多观察,即每十分钟一次。
之前学习了如何获取每个id在两个连续周期之间values的变化总数:
data.groupby(data.index).values.apply(lambda x: (x != x.shift()).sum() - 1)
这很好用,而且速度非常快。现在,我有兴趣在 df 中添加一个新列。如果当前行和上一行之间有变化,它应该是一个虚拟指示 values 中的每一行。因此,结果如下:
=>
id time values change
0 1 2017-01-01 12:00:00 10 0
1 2 2017-01-01 12:00:00 11 0
2 3 2017-01-01 12:00:00 12 0
3 1 2017-01-01 12:10:00 10 0
4 2 2017-01-01 12:10:00 12 1
5 3 2017-01-01 12:10:00 13 1
6 1 2017-01-01 12:20:00 10 0
7 2 2017-01-01 12:20:00 13 1
8 3 2017-01-01 12:20:00 13 0
在折腾之后,我想出了一个解决方案。但是,它真的很慢。它不会在我相当大的实际数据集上运行:
def calc_change(x):
x = (x != x.shift())
x.iloc[0,] = False
return x
changes = data.groupby(data.index, as_index=False).values.apply(
calc_change).reset_index().iloc[:,2]
data = data.sort_index().reset_index()
data.loc[changes, 'change'] = 1
data = data.fillna(0)
我相信有更好的,感谢任何帮助!
【问题讨论】:
标签: python pandas dataframe pandas-groupby