我正面临 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)
上面给出了以下回溯:
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.
我确定这不是错误,但我在使用滚动窗口功能时犯了一个愚蠢的错误。虽然我无法弄清楚错误是什么,但我可以发誓这适用于以前版本的 Pandas。这提醒了我,我运行这段代码的版本是 1.1.0rc0
pickle 格式的示例数据是 here .看起来像这样:
>>> 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
最佳答案
任何低于 0.23 的版本,值总是作为 ndarray 传递。 rolling apply
的选项 raw
是从 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
您在旧 pandas 上没有看到任何错误或警告,所以我猜您的旧版本是 < 0.23。
从 1.0.0+ 版本开始,rolling
正式默认将值作为 series
(即 raw=False
)传递给 apply
关于你的错误,我猜这是一个错误,它只会在 沿
滚动应用时出现。强>axis = 1
我检查了 0.24 版本,这个错误已经存在。因此,它可能出现在将值作为 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
看看上面的错误回溯:
...
File "/usr/lib/python3.8/site-packages/pandas/core/window/rolling.py", line 1414, in apply_func
values = Series(values, index=self.obj.index)
...
它尝试从 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': {}}
所以,self.obj
就是 df
本身。这意味着 self.obj.index
是 df.index
并且它的长度是 2
In [19]: df.index.size
Out[19]: 2
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
...
如您所见,每行的长度为 3
,而 df.index
的长度为 2,因此会抛出 ValueError。
这是一个错误,所以与此同时,您需要使用参数 raw = True
指定您的rolling apply
来解决这个问题
关于python-3.x - 滚动窗口问题 : ValueError: Length of passed values is 3, 索引意味着 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63155830/