python - 在 pandas groupby 中取不同大小的组之间的差异
问题描述
我需要计算数据中连续时间组之间的差异,如下所示
from io import StringIO
import pandas as pd
strio = StringIO("""\
date feat1 feat2 value
2016-10-15T00:00:00 1 1 0.0
2016-10-15T00:00:00 1 2 1.0
2016-10-15T00:00:00 2 1 2.0
2016-10-15T00:00:00 2 2 3.0
2016-10-15T00:01:00 1 1 8.0
2016-10-15T00:01:00 1 2 5.0
2016-10-15T00:02:00 1 1 8.0
2016-10-15T00:02:00 1 2 12.0
2016-10-15T00:02:00 2 1 10.0
2016-10-15T00:02:00 2 2 11.0
2016-10-15T00:03:00 1 1 12.0
2016-10-15T00:03:00 1 2 13.0
2016-10-15T00:03:00 2 1 14.0
2016-10-15T00:03:00 2 2 15.0""")
我可以使用xarray
库来做到这一点
df = pd.read_table(strio, sep='\s+')
dims = df.columns.values[:3].tolist()
df.set_index(dims, inplace=True) # needed to convert to xarray dataset
dataset = df.to_xarray()
diff_time = dataset.diff(dim=dims[0]) # take the diff in time
print(diff_time.to_dataframe().reset_index())
印刷
date feat1 feat2 value
0 2016-10-15T00:01:00 1 1 8.0
1 2016-10-15T00:01:00 1 2 4.0
2 2016-10-15T00:01:00 2 1 NaN
3 2016-10-15T00:01:00 2 2 NaN
4 2016-10-15T00:02:00 1 1 0.0
5 2016-10-15T00:02:00 1 2 7.0
6 2016-10-15T00:02:00 2 1 NaN
7 2016-10-15T00:02:00 2 2 NaN
8 2016-10-15T00:03:00 1 1 4.0
9 2016-10-15T00:03:00 1 2 1.0
10 2016-10-15T00:03:00 2 1 4.0
11 2016-10-15T00:03:00 2 2 4.0
所以在瞬间 2016-10-15T00:01:00 我有 feat1:2 缺少相关的差异是 nan
如何以矢量化的方式在纯熊猫中做到这一点?使用 nan 填充构建原始数据框(因此组大小相同)是一种选择,但应避免
一个笨拙的方法是:
dfs = []
for k, v in zip(itertools.islice(df.groupby(level=0).groups.values(), 1, None),
df.groupby(level=0).groups.values()):
# print(df.loc(axis=0)[k.values] , df.loc(axis=0)[v.values])
diff = df.loc(axis=0)[k.values].reset_index(level=0, drop=True) - \
df.loc(axis=0)[v.values].reset_index(level=0, drop=True)
diff = pd.concat([diff], keys=[k.values[0][0]], names=['date'])
dfs.append(diff)
print(pd.concat(dfs).reset_index())
它确实打印相同的输出,但它不是矢量化的
解决方案
更新的解决方案:
df.unstack(0)['value']\
.diff(axis=1)\
.dropna(how='all', axis=1)\
.unstack([0,1])\
.rename('value')\
.reset_index()
输出:
date feat1 feat2 value
0 2016-10-15T00:01:00 1 1 8.0
1 2016-10-15T00:01:00 1 2 4.0
2 2016-10-15T00:01:00 2 1 NaN
3 2016-10-15T00:01:00 2 2 NaN
4 2016-10-15T00:02:00 1 1 0.0
5 2016-10-15T00:02:00 1 2 7.0
6 2016-10-15T00:02:00 2 1 NaN
7 2016-10-15T00:02:00 2 2 NaN
8 2016-10-15T00:03:00 1 1 4.0
9 2016-10-15T00:03:00 1 2 1.0
10 2016-10-15T00:03:00 2 1 4.0
11 2016-10-15T00:03:00 2 2 4.0
细节:
创建一个三级MultiIndex后,首先让我们unstack level 0,date,它将日期从行移动到列,然后在列上使用diff,最后使用dropna删除第一个日期,其中整个列是nan,unstack feat1和feat2重新创建多索引并转换回数据框。
推荐阅读
- javascript - 如何加载双倍空间值以下拉角度 6
- listview - 如何在颤动中实现如下设计?
- python - 如何在 python 中使用 split 和 join 从现有列创建新列?
- android - 如何刷新云firebase数据库,有时它会显示旧值
- python - 在 Pycharm 中以与在 Jupyter 中相同的方式可视化数据?
- angular - Angular - 删除具有相同名称元素的数组中的重复项
- pandas - 从另一列的 groupby 的结果创建一个新列
- docker - (模拟的)PPC64 Linux 上的 backtrace() 段错误
- laravel - curl 中的 Laravel 5.8 post call 效果很好,但不适用于 guzzle
- reactjs - 如何修复 componentDidUpdate 一遍又一遍地发送请求