代码之家  ›  专栏  ›  技术社区  ›  Maganna Dev

在时间索引数据帧中创建额外列

  •  1
  • Maganna Dev  · 技术社区  · 7 年前

    我现在有一个日期时间索引数据框,有三列:

                         Glucosa   Insulina  Carbs
    Hour
    2018-05-16 06:43:00    156.0       7.0   65.0
    2018-05-16 07:43:00    170.0       0.0   65.0
    2018-05-16 08:45:00    185.0       2.0    0.0
    2018-05-16 09:45:00    150.0       0.0    0.0
    2018-05-16 10:45:00     80.0       0.0    0.0
         ...
    

    我想创建三个额外的列,保存从当前索引开始一小时后索引的值,最后得到如下结果:

                         Glucosa   Insulina  Carbs  Glucosa1  Insulina1  Carbs1
    Hour
    2018-05-16 06:43:00    156.0       7.0   65.0      170.0        0.0   65.0
    2018-05-16 07:43:00    170.0       0.0   65.0      185.0        2.0    0.0
    2018-05-16 08:45:00    185.0       2.0    0.0      150.0        0.0    0.0
    2018-05-16 09:45:00    150.0       0.0    0.0       80.0        0.0    0.0
    2018-05-16 10:45:00     80.0       0.0    0.0       ...         ...    ...
         ...
    

    我已经定义了一个函数,该函数创建了一个包含“glucoseA1”、“Insulina1”、“Carbs1”列的数据帧,但它的性能非常差,我想让它运行得更快。

    我使用以下方法在代码中分析不同函数使用的时间:

    start = time.time()
      # foo() 
    end = time.time()
    print(f' Time required to execute foo() : {end - start}')
    

    与输出0.366158秒的类似函数(在数据帧的行上迭代)相比,函数nn_format_df()的输出时间(平均)为8.331165秒。

    在创建了一个新的数据帧并调用了原始数据帧上的函数后,我将它们合并以获得所需的数据帧。

    df2 = nn_format_df(df)
    df = df.join([df2])
    

    功能:

    def nn_format_df( df : pd.core.frame.DataFrame ) -> pd.core.frame.DataFrame:
    
      _indices   : pd.core.indexes.datetimes.DatetimeIndex = [ idx for idx in df.index ]
      indices    = _indices[:-60]
      _df        : pd.core.frame.DataFrame = df.copy()
      _df1       : pd.core.frame.DataFrame
      _glc1      : pd.core.series.Series   = pd.Series(pd.np.nan, index=_indices)
      _insu1     : pd.core.series.Series   = pd.Series(pd.np.nan, index=_indices)
      _carbs1    : pd.core.series.Series   = pd.Series(pd.np.nan, index=_indices)
    
      aux        : pd._libs.tslibs.timestamps.Timestamp
      aux1       : pd._libs.tslibs.timestamps.Timestamp
      one        : datetime.timedelta = datetime.timedelta(hours=1) 
    
      for idx in indices:
        aux  = _df.ix[ idx, : ].name
        aux1 = aux + one
        _glc1[   idx ]  = _df.ix[ aux1, 'Glucosa' ]
        _insu1[  idx ]  = _df.ix[ aux1, 'Insulina' ]
        _carbs1[ idx ]  = _df.ix[ aux1, 'Carbs' ]
    
      _df1 = pd.DataFrame({ 'Glucosa1': _glc1,\
                           'Insulina1': _insu1,\
                              'Carbs1': _carbs1
                          }, index=_indices)
    
      return _df1
    

    总而言之:

    • 如果您能就如何改进功能提出任何意见,我将不胜感激,这样就不会花费太长时间。
    • 一种更好、更具Pythonic或pandas-y风格的获取所需数据帧的方法是受欢迎的。我是熊猫队的新手,我知道我对该功能的实现是一种完全幼稚的方法。
    1 回复  |  直到 7 年前
        1
  •  3
  •   ALollz    7 年前

    你可以用 .shift ,这改变了整个 DataFrame .就用吧 pd.concat 将它们结合在一起;这个 axis=1 参数指定要附加新列而不是行。

    import pandas as pd
    pd.concat([df, df.shift(-1).rename(columns=dict((elem, elem+'1') for elem in df.columns))], axis=1)
    

    以上代码提供了以下输出:

                         Glucosa  Insulina  Carbs  Glucosa1  Insulina1  Carbs1
    Hour                                                                      
    2018-05-16 06:43:00    156.0       7.0   65.0     170.0        0.0    65.0
    2018-05-16 07:43:00    170.0       0.0   65.0     185.0        2.0     0.0
    2018-05-16 08:45:00    185.0       2.0    0.0     150.0        0.0     0.0
    2018-05-16 09:45:00    150.0       0.0    0.0      80.0        0.0     0.0
    2018-05-16 10:45:00     80.0       0.0    0.0       NaN        NaN     NaN