AssertionError:当unstack()数据帧时,blk ref_locs中的间隙

时间:2018-03-26 00:21:20

标签: python pandas dataframe

我正在尝试在Pandas数据帧中取消堆栈()数据,但我一直收到此错误,我不知道为什么。到目前为止,我的代码是我的数据样本。我尝试修复它的方法是删除所有的行,其中voteId不是数字,这对我的实际数据集不起作用。这种情况发生在Anaconda笔记本(我正在开发的地方)和我的生产环境中,当我部署代码时。

我无法弄清楚如何在我的示例代码中重现错误...可能是由于在实例化数据帧时不存在的类型转换问题,就像我在样本中所做的那样?

#dataset simulate likely input
# d = {'vote': [100, 50,1,23,55,67,89,44], 
#      'vote2': [10, 2,18,26,77,99,9,40], 
#      'ballot1': ['a','b','a','a','b','a','c','c'],
#      'voteId':[1,2,3,4,5,'aaa',7,'NaN']}
# df1=pd.DataFrame(d)
#########################################################

df1=df1.drop_duplicates(['voteId','ballot1'],keep='last')

s=df1[:10].set_index(['voteId','ballot1'],verify_integrity=True).unstack()
s.columns=s.columns.map('(ballot1={0[1]}){0[0]}'.format) 
dflw=pd.DataFrame(s)

完整的错误消息/堆栈跟踪:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-10-0a520180a8d9> in <module>()
     22 df1=df1.drop_duplicates(['voteId','ballot1'],keep='last')
     23 
---> 24 s=df1[:10].set_index(['voteId','ballot1'],verify_integrity=True).unstack()
     25 s.columns=s.columns.map('(ballot1={0[1]}){0[0]}'.format)
     26 dflw=pd.DataFrame(s)

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in unstack(self, level, fill_value)
   4567         """
   4568         from pandas.core.reshape.reshape import unstack
-> 4569         return unstack(self, level, fill_value)
   4570 
   4571     _shared_docs['melt'] = ("""

~/anaconda3/lib/python3.6/site-packages/pandas/core/reshape/reshape.py in unstack(obj, level, fill_value)
    467     if isinstance(obj, DataFrame):
    468         if isinstance(obj.index, MultiIndex):
--> 469             return _unstack_frame(obj, level, fill_value=fill_value)
    470         else:
    471             return obj.T.stack(dropna=False)

~/anaconda3/lib/python3.6/site-packages/pandas/core/reshape/reshape.py in _unstack_frame(obj, level, fill_value)
    480         unstacker = partial(_Unstacker, index=obj.index,
    481                             level=level, fill_value=fill_value)
--> 482         blocks = obj._data.unstack(unstacker)
    483         klass = type(obj)
    484         return klass(blocks)

~/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py in unstack(self, unstacker_func)
   4349         new_columns = new_columns[columns_mask]
   4350 
-> 4351         bm = BlockManager(new_blocks, [new_columns, new_index])
   4352         return bm
   4353 

~/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py in __init__(self, blocks, axes, do_integrity_check, fastpath)
   3035         self._consolidate_check()
   3036 
-> 3037         self._rebuild_blknos_and_blklocs()
   3038 
   3039     def make_empty(self, axes=None):

~/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py in _rebuild_blknos_and_blklocs(self)
   3127 
   3128         if (new_blknos == -1).any():
-> 3129             raise AssertionError("Gaps in blk ref_locs")
   3130 
   3131         self._blknos = new_blknos

AssertionError: Gaps in blk ref_locs

2 个答案:

答案 0 :(得分:1)

我使用您的示例代码进行了一些测试。

观察1:

这是关于该问题的一个可能的最小可验证代码:

import pandas as pd
from IPython.display import display

#dataset simulate likely input
d = {'vote': [100, 50,1,23,55,67,89,44], 
     'vote2': [10, 'a',18,55,77,99,9,40], 
     'ballot1': [1,None,3,4,5,6,7,8],
     'voteId':[1,2,3,4,5,6,7,8]}
df1 = pd.DataFrame(d)
#########################################################

df1 = df1.drop_duplicates(['voteId','ballot1'],keep='last')

s = df1[:10].reset_index().set_index(['voteId','ballot1'],verify_integrity=True).unstack()
s.columns=s.columns.map('(ballot1={0[1]}){0[0]}'.format)
dflw=pd.DataFrame(s)
display(dflw)

做出决定,数据可以是我对其进行一点修改并发现以下内容(基于此示例):

1) For some reason the indexes has to be very similar to each other, 
   but differ by one None in one of them.
2) vote and vote2 need to have one number in common with each other
3) another vote need to include anomality (letter or None)

观察2:

我还制作了另一个数据集(可能更接近你的数据集):

d = {'vote': [10, None,2,23,55,67,89,44],
     'vote2': [10,2,3,55,77,99,9,40],
     'ballot1': [1,None,3,4,5,6,7,8],
     'voteId':['a','b','a','a','c','a','c','a']}
df1 = pd.DataFrame(d)

有趣的是,ballot1和voteId的顺序与你的情况不同,并且它们的顺序与你的顺序不同,效果很好。

我的观察结果是ballot1是真正需要上限失败的一个指数,一个投票是无,并且需要投票系列之间的共享值。

<强>讨论

如果可能,ballot1和voteId(索引)都只有整数,但是ballot1也有一些异常,这取决于投票列中的数据,可能会引发此错误。

当索引列值有间隙并且可能与您拥有的df1 [:10]命令相关时,会引发断言,例如ZevGithub上的问题发表了评论。

在我的示例中,尽管Github建议的解决方法没有效果。最好的办法是摆脱已经处于良好状态的数据中的无值。

<强>图片的标题说明:

我不知道ballot1数据是否允许有整数,但至少如果是,则存在这种情况,可能发生错误。这些是否有用取决于您的案例,在撰写本文时您的问题并不清楚。现在你有一些指针可以尝试至少。

答案 1 :(得分:1)

要获取实际数据触发异常,请添加额外的调试信息

  

修改~/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py

class BlockManager()

添加行
def __init__(self)
    print('BlockManager blocks')
    pprint(self.blocks)
    print('BlockManager axes')
    pprint(self.axes)

您将获得数据:

_unstack_frame level -1 fill_value None 

                 vote  vote2
ballot1 voteId              
NaN     xx      100.0   10.0
False   aaa      50.1    2.0
-1      \n        1.0   18.0
True    NaN      23.0   26.0
b       False    55.0   77.0
a       \        67.0   99.0
c                89.0    9.0
        8        44.0    NaN
  

修改~/anaconda3/lib/python3.6/site-packages/pandas/core/reshape/reshape.py

def __unstack_frame(self, ...)
    from pprint import pprint
    print('_unstack_frame level {} fill_value {} {}'.format(level, fill_value, type(obj)))
    pprint(obj)

您将看到数据:


BlockManager blocks
(FloatBlock: slice(0, 16, 1), 16 x 8, dtype: float64,)
BlockManager axes
[MultiIndex(levels=[[u'vote', u'vote2'], [False, 8, u'\n', u' ', u'\', u'aaa', u'xx']],
           labels=[[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [-1, 0, 1, 2, 3, 4, 5, 6, -1, 0, 1, 2, 3, 4, 5, 6]],
           names=[None, u'voteId']),
 Index([nan, -1, False, True, u'', u'a', u'b', u'c'], dtype='object', name=u'ballot1')]

我确实用另一个例子触发了一个例外:

  File "/usr/lib64/python2.7/site-packages/pandas/core/internals.py", line 2902, in _rebuild_blknos_and_blklocs
    raise AssertionError("Gaps in blk ref_locs")
AssertionError: Gaps in blk ref_locs


带调试信息

BlockManager blocks
(FloatBlock: [-1, -1, -1], 3 x 2, dtype: float64,)
BlockManager axes
[Index([aaa, bbb, ccc], dtype='object'), Int64Index([0, 1], dtype='int64')]