代码之家  ›  专栏  ›  技术社区  ›  Mr_and_Mrs_D

以大熊猫不同体型群体间的差异为例

  •  1
  • Mr_and_Mrs_D  · 技术社区  · 6 年前

    我需要计算如下数据中连续时间组之间的差异

    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,我有一个特点1: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())
    

    它打印相同的输出,但没有矢量化

    1 回复  |  直到 6 年前
        1
  •  2
  •   Scott Boston    6 年前

    更新的解决方案:

    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
    

    细节:

    创建三级多索引后,首先让我们取消对0级日期的跟踪,它将日期从一行移动到另一列,然后对列使用diff,最后使用dropna删除第一个日期,其中整列为nan,取消跟踪feat1和feat2以重新创建多索引并转换回数据帧。