ValueError:在 groupby 对象上调用 pandas value_counts() 时,操作数无法与形状一起广播

Sal*_*lly 3 python numpy broadcasting pandas

我知道对此错误消息有很多疑问。然而我还没有找到一个有这个确切问题的人。

我正在尝试对 pandas DataFrame 进行分组并计算值:

allfactor = dataframe.groupby(factor)[reference_area].value_counts()
Run Code Online (Sandbox Code Playgroud)

其中factor和reference_area是数据框中的列名称。这适用于某些列,例如DGD015,但不适用于包括factor在内的其他列。
它给了我错误:

ValueError: operands could not be broadcast together with shape (421,) (419,)
Run Code Online (Sandbox Code Playgroud)

我将把完整的错误消息放在这个问题的末尾。
分组本身有效:

In: grouped = data.groupby(factor)[reference_area]
    grouped
Out: <pandas.core.groupby.generic.SeriesGroupBy object at 0x0000000B39D0F5F8>
Run Code Online (Sandbox Code Playgroud)

我可以看到这是一个 numpy 广播错误,因为尺寸不具有相同的形状而发生。并且有一些解决方法,例如在尝试乘以不“适合”且无法从中得到任何维度的维度时,使用[:, np.newaxis]地球科学研究计算)或[:,None]如何像计算机科学家一样思考:使用 Python 3 学习)伸展。

但是,当numpy中发生错误时,我不知道如何执行此操作,这是由pandas调用的,而pandas是通过调用value_counts()来调用的。

有人在这里有解决方法的想法吗?

我如何在这里访问 numpy 来告诉它只添加包含 NAN 的新轴以使尺寸适合?

这是完整的错误消息:

ValueError          Traceback (most recent call last)
ipython-input-5-013b5262b34f> in module>()
----> 1 trial = get_positives_threshold(data, 'SHB23D', 'HV001', threshold=90)
      2 print(trial)
ipython-input-3-80d69965e883> in get_positives_threshold(dataframe, factor, reference_area, threshold)
---> 33         allfactor = dataframe.groupby(factor)[reference_area].value_counts()
~\Documents\anaconda3\lib\site-packages\pandas\core\groupby\generic.py in value_counts(self, normalize, sort, ascending, bins, dropna)
-> 1139         labels = list(map(rep, self.grouper.recons_labels)) + [llab(lab, inc)]`
`~\Documents\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in repeat(a, repeats, axis)
    421     repeated_array : ndarray
    422         Output array which has the same shape as a, except along
--> 423         the given axis.
~\Documents\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
     50     try:
     51         return getattr(obj, method)(*args, **kwds)
---> 52 
     53     # An AttributeError occurs if the object does not have
     54     # such a method in its class.`


ValueError: operands could not be broadcast together with shape (421,) (419,)
Run Code Online (Sandbox Code Playgroud)

以下是有关数据框的一些信息:

最初是一个 .sav SPSS 文件,后来转换为 Feather 文件。然后使用 pandas.read_feather(path_to_file) 读入。所有列的数据都是 dtype 分类的。大多数列的原始值包含 NaN、作为字符串的整数和字符串,但所有这些都存储为类型分类。

  reference_area   HV002   HV003  [...] DGD015    [...] factor    [...]
1 '10001'          'NaN'   'Yes'  [...] 'Refused' [...] '90'      [...]
2 '10001'          'No'    'NaN'  [...] '140'     [...] '80'      [...]
3 '24736'          'Yes'   'No'   [...] '78'      [...] 'Nan'     [...]
4 '24736'          'Yes'   'No'   [...] 'Other'   [...] 'Technical Problem'
Run Code Online (Sandbox Code Playgroud)

值具有代表性,但混合,并且列名称已更改以掩盖原始数据。

Pandas 版本 0.24.1
Numpy 版本 1.15.4
Python 版本 3.6.5
在我的环境中使用上述版本的 jupyter 笔记本中使用 Anaconda 3。

预期输出:

In: dataframe.groupby(factor)[reference_area].value_counts()
Out: factor  reference_area 
0                  121640.0     1
1                  52675.0      1
                   181826.0     1
10                 40812.0      1
                   340804.0     2
                   360756.0     1
100                70679.0     18
                   70251.0     14
                   70019.0     13
                   70728.0     11
                   120070.0    11
                               ..
Refused            90008.0      1
Run Code Online (Sandbox Code Playgroud)

Sal*_*lly 10

问题似乎出在未观察到的类别上。来自 groupby 的 pandas 文档:

使用分类石斑鱼(作为单个石斑鱼或作为多个石斑鱼的一部分)时,observed 关键字控制是否返回所有可能的石斑鱼值 (observed=False) 的笛卡尔积,或仅返回那些被观察到的石斑鱼值 (observed=True) )。

在我的具体情况下计算笛卡尔积最终会导致广播错误。这就是为什么有些列起作用而另一些列不起作用:那些起作用的列没有任何未观察到的类别,而那些不起作用的列则有未观察到的类别。

为了避免出现此问题,请observed = True在分组时进行设置。这意味着groupby将仅使用观察到的类别(即存在条目的那些类别)。就我而言,情况是:
allfactor = dataframe.groupby(factor, observed=True)[reference_area].value_counts()

据我的测试显示,这不会导致丢失数据帧的条目以供进一步分析。没有未观察到的类别的条目(即使是 NaN 值),因此我们不会因为仅使用观察到的类别而丢失任何条目。但请注意,如果您确实想分析这些未观察到的类别,这不是您正在寻找的解决方案。