【问题标题】:pandas resampler agg cannot apply on list of functionspandas resampler agg 不能应用于函数列表
【发布时间】:2021-12-24 09:44:18
【问题描述】:

当有要应用r.apply({"price" : vwap, "qty": sum_qty, "quoteQty": sum_quoteQty}) 的函数列表时,我对pandas.Resampler.agg 有疑问。它总是返回类似AttributeError: 'Series' object has no attribute 'price' 的错误。但它只适用于一个函数r.apply(vwap)。

我的数据框具有price、qty 等属性:

我定义了要在 Resampler 上应用的函数列表。我添加了一些打印来调试:

如果我使用函数列表,则重采样器无法找到我的数据帧的属性price:

AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_939/4117684543.py in <module>
----> 1 r.apply({"price" : vwap, "qty": sum_qty, "quoteQty": sum_quoteQty})

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/resample.py in aggregate(self, func, *args, **kwargs)
    332     def aggregate(self, func, *args, **kwargs):
    333 
--> 334         result = ResamplerWindowApply(self, func, args=args, kwargs=kwargs).agg()
    335         if result is None:
    336             how = func

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/apply.py in agg(self)
    159 
    160         if is_dict_like(arg):
--> 161             return self.agg_dict_like()
    162         elif is_list_like(arg):
    163             # we require a list, but not a 'str'

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/apply.py in agg_dict_like(self)
    433         else:
    434             # key used for column selection and output
--> 435             results = {
    436                 key: obj._gotitem(key, ndim=1).agg(how) for key, how in arg.items()
    437             }

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/apply.py in <dictcomp>(.0)
    434             # key used for column selection and output
    435             results = {
--> 436                 key: obj._gotitem(key, ndim=1).agg(how) for key, how in arg.items()
    437             }
    438 

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/groupby/generic.py in aggregate(self, func, engine, engine_kwargs, *args, **kwargs)
    263 
    264             try:
--> 265                 return self._python_agg_general(func, *args, **kwargs)
    266             except KeyError:
    267                 # TODO: KeyError is raised in _python_agg_general,

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/groupby/groupby.py in _python_agg_general(self, func, *args, **kwargs)
   1308             try:
   1309                 # if this function is invalid for this dtype, we will ignore it.
-> 1310                 result = self.grouper.agg_series(obj, f)
   1311             except TypeError:
   1312                 warnings.warn(

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/groupby/ops.py in agg_series(self, obj, func, preserve_dtype)
   1026 
   1027         else:
-> 1028             result = self._aggregate_series_fast(obj, func)
   1029 
   1030         npvalues = lib.maybe_convert_objects(result, try_float=False)

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/groupby/ops.py in _aggregate_series_fast(self, obj, func)
   1249         #  - len(self.bins) > 0
   1250         sbg = libreduction.SeriesBinGrouper(obj, func, self.bins)
-> 1251         result, _ = sbg.get_result()
   1252         return result
   1253 

/SSD/lime/conda/lib/python3.9/site-packages/pandas/_libs/reduction.pyx in pandas._libs.reduction.SeriesBinGrouper.get_result()

/SSD/lime/conda/lib/python3.9/site-packages/pandas/_libs/reduction.pyx in pandas._libs.reduction._BaseGrouper._apply_to_group()

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/groupby/groupby.py in <lambda>(x)
   1294     def _python_agg_general(self, func, *args, **kwargs):
   1295         func = com.is_builtin_func(func)
-> 1296         f = lambda x: func(x, *args, **kwargs)
   1297 
   1298         # iterate through "columns" ex exclusions to populate output dict

/tmp/ipykernel_939/2003501728.py in vwap(x)
      2     print("it's vwap")
      3     print(x)
----> 4     p = x.price
      5     print("it's p")
      6     print(p)

/SSD/lime/conda/lib/python3.9/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5485         ):
   5486             return self[name]
-> 5487         return object.__getattribute__(self, name)
   5488 
   5489     def __setattr__(self, name: str, value) -> None:

AttributeError: 'Series' object has no attribute 'price'

但是,它可以与单个函数 r.apply(vwap) 一起正常工作,并且可以检索属性 price 和 qty:

调试打印验证了我的假设:

2021-09-01 00:00:00.023    1391646824
2021-09-01 00:00:00.093    1391646825
2021-09-01 00:00:00.994    1391646826
2021-09-01 00:00:00.994    1391646827
2021-09-01 00:00:00.994    1391646828
2021-09-01 00:00:00.994    1391646829
Name: trade Id, dtype: int64
it's vwap
                           trade Id     price    qty  quoteQty  isBuyerMaker
time                                                                        
2021-09-01 00:00:00.023  1391646824  47150.32  0.002     94.30          True
2021-09-01 00:00:00.093  1391646825  47150.33  0.002     94.30         False
2021-09-01 00:00:00.994  1391646826  47150.33  0.021    990.15         False
2021-09-01 00:00:00.994  1391646827  47150.33  0.021    990.15         False
2021-09-01 00:00:00.994  1391646828  47152.97  0.002     94.30         False
2021-09-01 00:00:00.994  1391646829  47153.48  0.006    282.92         False
it's p
time
2021-09-01 00:00:00.023    47150.32
2021-09-01 00:00:00.093    47150.33
2021-09-01 00:00:00.994    47150.33
2021-09-01 00:00:00.994    47150.33
2021-09-01 00:00:00.994    47152.97
2021-09-01 00:00:00.994    47153.48
Name: price, dtype: float64
it's q
time
2021-09-01 00:00:00.023    0.002
2021-09-01 00:00:00.093    0.002
2021-09-01 00:00:00.994    0.021
2021-09-01 00:00:00.994    0.021
2021-09-01 00:00:00.994    0.002
2021-09-01 00:00:00.994    0.006
Name: qty, dtype: float64
it's vwap
Empty DataFrame
Columns: [trade Id, price, qty, quoteQty, isBuyerMaker]
Index: []
it's p
Series([], Name: price, dtype: float64)
it's q
Series([], Name: qty, dtype: float64)
it's vwap
                           trade Id     price    qty  quoteQty  isBuyerMaker
time                                                                        
2021-09-01 00:00:02.050  1391646830  47153.47  0.006    282.92          True
2021-09-01 00:00:02.889  1391646831  47153.47  0.054   2546.28          True
2021-09-01 00:00:02.889  1391646832  47153.47  0.050   2357.67          True
2021-09-01 00:00:02.889  1391646833  47153.47  0.050   2357.67          True
it's p
time
2021-09-01 00:00:02.050    47153.47
2021-09-01 00:00:02.889    47153.47
2021-09-01 00:00:02.889    47153.47
2021-09-01 00:00:02.889    47153.47
Name: price, dtype: float64
it's q
time
2021-09-01 00:00:02.050    0.006
2021-09-01 00:00:02.889    0.054
2021-09-01 00:00:02.889    0.050
2021-09-01 00:00:02.889    0.050
Name: qty, dtype: float64

但是当我尝试官方文档的示例时,即使使用函数列表也一切正常:

所以我真的不知道问题出在哪里......

【问题讨论】:

  • 只是在这里拍摄:在访问 cols 时尝试使用括号索引表示法,而不是点表示法,例如x['price'] 而不是 x.price 等。我曾经遇到过点符号的问题...
  • @user17242583 现在它得到一个 KeyError: 'price' 而不是 AttributeError...
  • 能否将创建r的代码添加到问题中?
  • @user17242583 非常标准:r = csv.head(10).resample('1s', label='right'),如果我删除label='right',结果是一样的。

标签: python pandas dataframe pandas-groupby


【解决方案1】:

哦等等。

提示在错误信息中:

'Series' object has no attribute 'price'

这是因为调用 vwap 函数时使用的 x 是 Series。这是price 列,因为这就是您所说的vwap 应该得到的! ({"price": vwap, ...})

默认情况下,apply() 像大多数其他函数一样按列排列。如果你想apply()逐行,使用apply(..., axis=1)。

您可能需要更改传递给 apply() 的 dict,但这应该会让您重新开始 :)

【讨论】:

  • 我确实尝试过apply(..., axis=1) 并且错误消息是相同的......我不太确定如何更改我的字典,因为我确实需要对 2 列进行操作。
  • 重点是我需要 x 成为一个 DataFrame,就像 r.apply(vwap) 的情况一样,但我看不到任何选项,除了为结果中的每一列多次调用 r.apply(func)。
猜你喜欢
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 2019-08-02
  • 2017-04-06
  • 2020-12-07
  • 1970-01-01
相关资源
最近更新 更多