代码之家  ›  专栏  ›  技术社区  ›  yatu Sayali Sonawane

带字符串的滚动求和

  •  2
  • yatu Sayali Sonawane  · 技术社区  · 5 年前

    假设我有一个包含字符串的数据帧,例如:

    df = pd.DataFrame({'col1':list('some_string')})
    
        col1
    0     s
    1     o    
    2     m
    3     e
    4     _
    5     s
    ...
    

    我正在寻找一种方法来应用滚动窗口 col1 并以一定的窗口大小连接字符串。比如说 window=3 ,我想获得(无最少观察次数):

         col1
    0     s
    1     so
    2     som
    3     ome
    4     me_
    5     e_s
    6     _st
    7     str
    8     tri
    9     rin
    10    ing
    

    我已经试过了显而易见的解决办法 rolling 在处理对象类型时失败:

    df.col1.rolling(3, min_periods=0).sum()
    df.col1.rolling(3, min_periods=0).apply(''.join)
    

    两者都提出:

    无法处理此类型->对象

    是否有一种通用的方法(不使用 shift 来匹配这个特定的 w=3 )?

    0 回复  |  直到 5 年前
        1
  •  2
  •   Chris    5 年前

    使用 pd.Series.cumsum 似乎在工作(尽管有点低效):

    df['col1'].cumsum().str[-3:]
    

    输出:

    0       s
    1      so
    2     som
    3     ome
    4     me_
    5     e_s
    6     _st
    7     str
    8     tri
    9     rin
    10    ing
    Name: col1, dtype: object
    
        2
  •  2
  •   IanS    5 年前

    换个系列怎么样?

    df.col1.shift(2).fillna('') + df.col1.shift().fillna('') + df.col1
    

    推广到任何数字:

    pd.concat([df.col1.shift(i).fillna('') for i in range(3)], axis=1).sum(axis=1)
    
        3
  •  2
  •   vurmux    5 年前

    滚动的 works only with numbers :

    def _prep_values(self, values=None, kill_inf=True):
            if values is None:
                values = getattr(self._selected_obj, 'values', self._selected_obj)
            # GH #12373 : rolling functions error on float32 data
            # make sure the data is coerced to float64
            if is_float_dtype(values.dtype):
                values = ensure_float64(values)
            elif is_integer_dtype(values.dtype):
                values = ensure_float64(values)
            elif needs_i8_conversion(values.dtype):
                raise NotImplementedError...
        ...
        ...
    

    所以你应该手动构建它。以下是简单列表理解的可能变体之一(可能存在一种更为简单的方式):

    df = pd.DataFrame({'col1':list('some_string')})
    pd.Series([
        ''.join(df.col1.values[max(i-2, 0): i+1])
        for i in range(len(df.col1.values))
    ])
    
    0       s
    1      so
    2     som
    3     ome
    4     me_
    5     e_s
    6     _st
    7     str
    8     tri
    9     rin
    10    ing
    dtype: object