我对此感到难过 - 一反常态 - 互联网一直没什么帮助。我在Pandas工作,但我觉得这对于那些希望有效存储时间序列数据的人来说一定是个普遍问题。
我有很多标准的每日时间序列数据,其中值很少发生变化,如下所示:
Date Value
01/02/2014 .1
01/03/2014 .1
01/04/2014 .5
01/05/2014 .5
01/06/2014 .5
01/07/2014 .1
我会将数据转换为仅跟踪值更改的天数,因此上面的示例现在应该如下所示:
Date Value
01/02/2014 .1
01/04/2014 .5
01/07/2014 .1
不幸的是,使用类似drop_duplicates()
之类的内容会在值恢复为先前值(如上例中的.1)的情况下删除所需的值。
答案 0 :(得分:5)
使用shift
和all
的组合:
In [98]:
import io
temp = """Date,Value
01/02/2014,.1
01/03/2014,.1
01/04/2014,.5
01/05/2014,.5
01/06/2014,.5
01/07/2014,.1"""
df = pd.read_csv(io.StringIO(temp))
df
Out[98]:
Date Value
0 01/02/2014 0.1
1 01/03/2014 0.1
2 01/04/2014 0.5
3 01/05/2014 0.5
4 01/06/2014 0.5
5 01/07/2014 0.1
In [99]:
df.loc[(df.shift() != df).all(axis=1)]
Out[99]:
Date Value
0 01/02/2014 0.1
2 01/04/2014 0.5
5 01/07/2014 0.1
在这里,我们将移位(按1行)数据框与原始数据框进行比较,然后我们要比较每列并使用all
并传递axis=1
来实现此目标。
如果我们查看df.shift() != df
返回的内容,请进一步细分:
In [100]:
df.shift() != df
Out[100]:
Date Value
0 True True
1 True False
2 True True
3 True False
4 True False
5 True True
我们得到一个带有布尔值的数据框,但我们不能将其用作掩码,我们要检查所有行是否为True
,因此我们使用all
:
In [101]:
(df.shift() != df).all()
Out[101]:
Date True
Value False
dtype: bool
但是,默认情况下会检查列是否全部为True
,我们要检查行值,以便我们通过axis=1
:
In [102]:
(df.shift() != df).all(axis=1)
Out[102]:
0 True
1 False
2 True
3 False
4 False
5 True
dtype: bool
我们现在可以使用它作为我们的布尔掩码来实现我们想要的目标:
In [103]:
df.loc[(df.shift() != df).all(axis=1)]
Out[103]:
Date Value
0 01/02/2014 0.1
2 01/04/2014 0.5
5 01/07/2014 0.1