Pandas pd.cut on Timestamps - "ValueError: bins must increase monotonically"
Pandas pd.cut on Timestamps - "ValueError: bins must increase monotonically"
我正在尝试将时间序列数据拆分为这样的标记段:
import pandas as pd
import numpy as np
# Create example DataFrame of stock values
df = pd.DataFrame({
'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
'price':(np.random.randn(100).cumsum() + 10) })
# Cut the date into sections
today = df['date'].max()
bin_edges = [pd.Timestamp.min, today - pd.Timedelta('14 days'), today - pd.Timedelta('7 days'), pd.Timestamp.max]
df['Time Group'] = pd.cut(df['date'], bins=bin_edges, labels=['history', 'previous week', 'this week'])
但即使 bin_edges
似乎单调递增,我还是收到错误消息..
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-42-00524c0a883b>", line 13, in <module>
df['Time Group'] = pd.cut(df['date'], bins=bin_edges, labels=['history', 'previous week', 'this week'])
File "C:\Anaconda3\lib\site-packages\pandas\core\reshape\tile.py", line 228, in cut
raise ValueError('bins must increase monotonically.')
ValueError: bins must increase monotonically.
In[43]: bin_edges
Out[43]:
[Timestamp('1677-09-21 00:12:43.145225'),
Timestamp('2011-01-11 00:00:00'),
Timestamp('2011-01-18 00:00:00'),
Timestamp('2262-04-11 23:47:16.854775807')]
为什么会这样?
这是 pandas 中的错误。您的边缘需要转换为数值才能执行 cut
,并且通过使用 pd.Timestamp.min
和 pd.Timestamp.max
您实际上是在 lower/upper 的边界处设置边缘64位整数可以表示什么。这会在尝试比较边缘的单调性时导致溢出,这使得它看起来不是单调递增的。
溢出演示:
In [2]: bin_edges_numeric = [t.value for t in bin_edges]
In [3]: bin_edges_numeric
Out[3]:
[-9223372036854775000,
1294704000000000000,
1295308800000000000,
9223372036854775807]
In [4]: np.diff(bin_edges_numeric)
Out[4]:
array([-7928668036854776616, 604800000000000, 7928063236854775807],
dtype=int64)
在解决此问题之前,我的建议是使用更接近实际日期但仍能达到相同最终结果的 lower/upper:
first = df['date'].min()
today = df['date'].max()
bin_edges = [first - pd.Timedelta('1000 days'), today - pd.Timedelta('14 days'),
today - pd.Timedelta('7 days'), today + pd.Timedelta('1000 days')]
我随意选择了 1000 天,您可以根据需要选择不同的值。通过这些修改,cut
应该不会引发错误。
我也遇到了同样的错误,但 Whosebug 上的 none 答案对我的情况有所帮助。在这里发帖是为了其他登陆这里寻找答案的人的利益。
bins 按升序获取值,在我的例子中,我按降序排列并得到相同的错误“ValueError:bins 必须单调增加”。
通过将顺序更改为升序来解决它。
我正在尝试将时间序列数据拆分为这样的标记段:
import pandas as pd
import numpy as np
# Create example DataFrame of stock values
df = pd.DataFrame({
'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
'price':(np.random.randn(100).cumsum() + 10) })
# Cut the date into sections
today = df['date'].max()
bin_edges = [pd.Timestamp.min, today - pd.Timedelta('14 days'), today - pd.Timedelta('7 days'), pd.Timestamp.max]
df['Time Group'] = pd.cut(df['date'], bins=bin_edges, labels=['history', 'previous week', 'this week'])
但即使 bin_edges
似乎单调递增,我还是收到错误消息..
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-42-00524c0a883b>", line 13, in <module>
df['Time Group'] = pd.cut(df['date'], bins=bin_edges, labels=['history', 'previous week', 'this week'])
File "C:\Anaconda3\lib\site-packages\pandas\core\reshape\tile.py", line 228, in cut
raise ValueError('bins must increase monotonically.')
ValueError: bins must increase monotonically.
In[43]: bin_edges
Out[43]:
[Timestamp('1677-09-21 00:12:43.145225'),
Timestamp('2011-01-11 00:00:00'),
Timestamp('2011-01-18 00:00:00'),
Timestamp('2262-04-11 23:47:16.854775807')]
为什么会这样?
这是 pandas 中的错误。您的边缘需要转换为数值才能执行 cut
,并且通过使用 pd.Timestamp.min
和 pd.Timestamp.max
您实际上是在 lower/upper 的边界处设置边缘64位整数可以表示什么。这会在尝试比较边缘的单调性时导致溢出,这使得它看起来不是单调递增的。
溢出演示:
In [2]: bin_edges_numeric = [t.value for t in bin_edges]
In [3]: bin_edges_numeric
Out[3]:
[-9223372036854775000,
1294704000000000000,
1295308800000000000,
9223372036854775807]
In [4]: np.diff(bin_edges_numeric)
Out[4]:
array([-7928668036854776616, 604800000000000, 7928063236854775807],
dtype=int64)
在解决此问题之前,我的建议是使用更接近实际日期但仍能达到相同最终结果的 lower/upper:
first = df['date'].min()
today = df['date'].max()
bin_edges = [first - pd.Timedelta('1000 days'), today - pd.Timedelta('14 days'),
today - pd.Timedelta('7 days'), today + pd.Timedelta('1000 days')]
我随意选择了 1000 天,您可以根据需要选择不同的值。通过这些修改,cut
应该不会引发错误。
我也遇到了同样的错误,但 Whosebug 上的 none 答案对我的情况有所帮助。在这里发帖是为了其他登陆这里寻找答案的人的利益。
bins 按升序获取值,在我的例子中,我按降序排列并得到相同的错误“ValueError:bins 必须单调增加”。
通过将顺序更改为升序来解决它。