代码之家  ›  专栏  ›  技术社区  ›  Divakar

pandas.factorize与自定义数组数据类型

  •  -1
  • Divakar  · 技术社区  · 5 年前

    # Setup
    In [11]: np.random.seed(0)
        ...: a = np.random.randint(0,9,(7,2))
        ...: a[2] = a[0]
        ...: a[4] = a[1]
        ...: a[6] = a[1]
    
    # Check values
    In [12]: a
    Out[12]: 
    array([[5, 0],
           [3, 3],
           [5, 0],
           [5, 2],
           [3, 3],
           [6, 8],
           [3, 3]])
    
    # Check its itemsize
    In [13]: a.dtype.itemsize
    Out[13]: 8
    

    让我们使用包含两个元素的自定义数据类型将每一行视为标量。我们将使用 void-dtype 为此目的。如文件所述-

    https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.dtypes.html#specifying-and-constructing-data-types , https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html#arrays-interface )在 stackoverflow Q&A ,似乎是-

    In [23]: np.dtype((np.void, 16)) # 8 is the itemsize, so 8x2=16
    Out[23]: dtype('V16')
    
    # Create new view of the input
    In [14]: b = a.view('V16').ravel()
    
    # Check new view array
    In [15]: b
    Out[15]: 
    array([b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
           b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
           b'\x05\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
           b'\x06\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'],
          dtype='|V16')
    
    # Use pandas.factorize on the new view
    In [16]: pd.factorize(b)
    Out[16]: 
    (array([0, 1, 0, 0, 1, 2, 1]),
     array(['\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
            '\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
            '\x06\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00'],
           dtype=object))
    

    1. 第一个输出(=0)的第四个元素看起来是错误的,因为它与第三个元素具有相同的ID,但是 b

    2. 为什么第二个输出具有对象dtype,而 V16 . 这是否也导致了 1. ?

    更大的问题可能是 pandas.factorize

    值:序列A 1-D序列。不是熊猫对象的序列 在因子分解之前被强制为ndarrays。

    系统设置:Ubuntu 16.04,Python:2.7.12,NumPy:1.16.2,Pandas:

    在Python-3.x上

    系统设置:Ubuntu 16.04,Python:3.5.2,NumPy:1.16.2,Pandas:

    运行相同的设置,我得到-

    In [18]: b
    Out[18]: 
    array([b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
           b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
           b'\x05\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
           b'\x06\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00',
           b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'],
          dtype='|V16')
    
    In [19]: pd.factorize(b)
    Out[19]: 
    (array([0, 1, 0, 2, 1, 3, 1]),
     array([b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
            b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00',
            b'\x05\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00',
            b'\x06\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00'],
           dtype=object))
    

    所以,第一个输出关闭 factorize

    编写问题/tl;dr

    使用这样的自定义数据类型:

    1. labels , uniques uniques大学 在Python2.x上输入数据?

    2. 为什么不同 在Python3.x上打字?

    0 回复  |  直到 5 年前
        1
  •  9
  •   nnnmmm kennytm    5 年前

    至于为什么 V16 被迫 object ,中的许多函数 pandas 将数据转换为内部函数可以处理的数据类型之一, here . 如果数据类型不在列表中,它将成为一个对象,pandas不会将结果转换回原始数据类型,它将出现。

    关于Python 2和Python 3之间的差异:两者只有一个pandas代码库,那么为什么它们会给出不同的结果呢?

    StringHashTable 对于因子分解,Python 3使用 PyObjectHashTable ,以及 字符串哈希表 在你的案例中给出了错误的结果。我相信这是因为 字符串哈希表 假设以零结尾,这不是字符串的情况,事实上,如果只将行与第一个零字节进行比较,则第一行和第四行看起来是相同的。

    更多细节:这个电话 ensure_object 返回Python2中的字符串数组,但Python3中的字节数组(如 b 前缀)。相应地,选择的哈希表 here