【问题标题】:Pandas DataFrame: How to do Set Union Aggregation over a rolling windowPandas DataFrame:如何在滚动窗口上设置联合聚合
【发布时间】:2019-03-16 14:43:15
【问题描述】:

我有一个数据框,其中一列中包含一组 id,另一列中包含日期:

import pandas as pd

df = pd.DataFrame([['2018-01-01', {1, 2, 3}],
                   ['2018-01-02', {3}],
                   ['2018-01-03', {3, 4, 5}],
                   ['2018-01-04', {5, 6}]],
                  columns=['timestamp', 'ids'])

df['timestamp'] = pd.to_datetime(df['timestamp'])
df.set_index('timestamp', inplace=True)

                     ids
timestamp               
2018-01-01     {1, 2, 3}
2018-01-02     {3}
2018-01-03     {3, 4, 5}
2018-01-04     {5, 6}

我正在寻找的是一个可以为我提供每天最后 x 天的 id 的函数。所以,假设 x=3,我希望结果是:

                     ids
timestamp               
2018-01-01     {1, 2, 3}
2018-01-02     {1, 2, 3}
2018-01-03     {1, 2, 3, 4, 5}
2018-01-04     {3, 4, 5, 6}

我试过了

df.rolling(3).agg(set.union)

但这会导致以下错误:

Traceback (most recent call last):
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 222, in _prep_values
    values = _ensure_float64(values)
  File "pandas\_libs\algos_common_helper.pxi", line 3182, in pandas._libs.algos.ensure_float64
  File "pandas\_libs\algos_common_helper.pxi", line 3187, in pandas._libs.algos.ensure_float64
TypeError: float() argument must be a string or a number, not 'set'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 1561, in aggregate
    return super(Rolling, self).aggregate(arg, *args, **kwargs)
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 321, in aggregate
    return self.apply(arg, raw=False, args=args, kwargs=kwargs)
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 1580, in apply
    func, raw=raw, args=args, kwargs=kwargs)
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 1003, in apply
    center=False, raw=raw)
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 844, in _apply
    values = self._prep_values(b.values)
  File "C:\Users\m.manhertz\Envs\demo-8EG6nosu\lib\site-packages\pandas\core\window.py", line 225, in _prep_values
    "".format(values.dtype))
TypeError: cannot handle this type -> object

【问题讨论】:

    标签: python pandas set union rolling-computation


    【解决方案1】:

    Pandas 并非旨在将 listsetdict 等可迭代对象保存在 pd.Series 对象中。因此,您的逻辑不可矢量化。您最好的选择可能是列表理解:

    import pandas as pd
    
    df = pd.DataFrame([['2018-01-01', {1, 2, 3}],
                       ['2018-01-02', {3}],
                       ['2018-01-03', {3, 4, 5}],
                       ['2018-01-04', {3, 6}]],
                      columns=['timestamp', 'ids'])
    
    df['timestamp'] = pd.to_datetime(df['timestamp'])
    df.set_index('timestamp', inplace=True)
    
    df['ids'] = [set.union(*df.iloc[max(0, i-2): i+1, 0]) for i in range(len(df.index))]
    
    print(df)
    
                            ids
    timestamp                  
    2018-01-01        {1, 2, 3}
    2018-01-02        {1, 2, 3}
    2018-01-03  {1, 2, 3, 4, 5}
    2018-01-04     {3, 4, 5, 6}
    

    【讨论】:

    • 嗯,这有点令人失望。尽管如此,这个解决方案仍然有效。您可能想澄清如何调整 x 的其他值的列表理解,例如对于x = 10,它将是[set.union(*df.iloc[max(0, i-9): i+1, 0]) for i in range(len(df.index))]
    猜你喜欢
    • 2019-03-24
    • 2021-08-12
    • 2020-12-25
    • 1970-01-01
    • 2021-08-26
    • 2017-06-02
    • 2020-04-21
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多