我遇到了 Pandas 的以下问题,并且无法识别出任何错误。
churned_or_dormant_customers_by_month = jobs_by_customer_and_month.fillna(0).rolling(2, 2, axis='columns').apply(lambda window: 1 if not window[1] and window[0] else 0).sum(skipna=True)
Run Code Online (Sandbox Code Playgroud)
上面给出了以下回溯:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 2059, in apply
return super().apply(
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 1388, in apply
return self._apply(
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 586, in _apply
result = np.apply_along_axis(calc, self.axis, values)
File "<__array_function__ internals>", line 5, in apply_along_axis
File "/usr/lib/python3.8/site-packages/numpy/lib/shape_base.py", line 379, in apply_along_axis
res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs))
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 576, in calc
return func(x, start, end, min_periods)
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 1414, in apply_func
values = Series(values, index=self.obj.index)
File "/usr/lib/python3.8/site-packages/pandas/core/series.py", line 313, in __init__
raise ValueError(
ValueError: Length of passed values is 3, index implies 2.
Run Code Online (Sandbox Code Playgroud)
我确信这不是一个错误,但我使用滚动窗口函数犯了一个愚蠢的错误。我不知道错误是什么,但我可以发誓这适用于 Pandas 的早期版本。这提醒我,我运行此代码的版本是1.1.0rc0
pickle 格式的示例数据位于此处。看起来像这样:
>>> jobs_by_customer_and_month
2019-1 2019-2 2019-3
1.0 1.0 1.0 1.0
2.0 2.0 2.5 2.1
Run Code Online (Sandbox Code Playgroud)
任何小于 0.23 的版本,值始终作为 ndarray 传递。选项raw是rolling apply从 0.23+ 版本开始实现的。从版本 0.23 到版本 < 1.0.0,raw默认为True. 但是,它会产生一个警告:
C:\Python\Python37-32\Scripts\ipython:3: FutureWarning: Currently, 'apply' passes
the values as ndarrays to the applied function. In the future, this will change
to passing it as Series objects. You need to specify 'raw=True' to keep the current
behaviour, and you can pass 'raw=False' to silence this warning
Run Code Online (Sandbox Code Playgroud)
您在旧的 pandas 上没有看到任何错误或警告,所以我猜您的旧版本 < 0.23。
从版本 1.0.0+ 开始,rolling官方默认将值传递为series(ie raw=False) 到apply
rolling apply关于您的错误,我猜这是一个错误,并且仅在时出现axis = 1。
我查了一下0.24版本,这个bug已经存在了。series因此,它可能出现在滚动对象传递值的实现中apply。但是,此错误仅在rolling apply沿columns(即axis=1)时出现。
在rolling apply沿着axis = 1并series作为值传递时,每个系列都是 中的一行df。在你的情况下,它的长度= 3。即它是df.shape[1]
df:
2019-1 2019-2 2019-3
1.0 1.0 1.0 1.0
2.0 2.0 2.5 2.1
In [13]: df.loc[1.0].size
Out[13]: 3
In [14]: df.shape[1]
Out[14]: 3
Run Code Online (Sandbox Code Playgroud)
只需查看上面的错误回溯即可:
...
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 1414, in apply_func
values = Series(values, index=self.obj.index)
...
Run Code Online (Sandbox Code Playgroud)
它尝试构建一个系列values并用作self.obj.index索引。self是滚动对象,obj是其属性。让我们检查一下 的值obj是什么:
In [17]: (df.fillna(0)
...: .rolling(window=3, axis='columns').__dict__
...: )
Out[17]:
{'obj': 2019-1 2019-2 2019-3
1.0 1.0 1.0 1.0
2.0 2.0 2.5 2.1,
'on': None,
'closed': None,
'window': 3,
'min_periods': None,
'center': False,
'win_type': None,
'win_freq': None,
'axis': 1,
'_cache': {'_on': Index(['2019-1', '2019-2', '2019-3'], dtype='object'),
'is_datetimelike': False},
'_numba_func_cache': {}}
Run Code Online (Sandbox Code Playgroud)
所以,self.obj就是它df本身。这意味着self.obj.index是df.index并且它的长度是2
In [19]: df.index.size
Out[19]: 2
Run Code Online (Sandbox Code Playgroud)
series根据index(文件内series.py)的长度检查数据长度的构造
...
if index is None:
if not is_list_like(data):
data = [data]
index = ibase.default_index(len(data))
elif is_list_like(data):
# a scalar numpy array is list-like but doesn't
# have a proper length
try:
if len(index) != len(data):
raise ValueError(
f"Length of passed values is {len(data)}, "
f"index implies {len(index)}."
)
except TypeError:
pass
...
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,每行的长度是32 df.index,所以它会抛出 ValueError。
这是一个错误,因此同时,您需要指定rolling applywith 参数raw = True来解决此问题
| 归档时间: |
|
| 查看次数: |
3720 次 |
| 最近记录: |