【问题标题】:Accessing the first items in a numpy array of tuples访问 numpy 元组数组中的第一项
【发布时间】:2015-05-28 12:07:42
【问题描述】:

我有一个 pandas 数据框,其中有一列包含由两个浮点数组成的元组,例如(1.1,2.2)。我希望能够生成一个包含每个元组的第一个元素的数组。我可以遍历每一行并获取每个元组的第一个元素,但数据帧包含近 400 万条记录,这种方法非常慢。 satoru 在 SO (stackoverflow.com/questions/6454894/reference-an-element-in-a-list-of-tuples) 上的回答建议使用以下机制:

>>> import numpy as np
>>> arr = np.array([(1.1,2.2),(3.3,4.4),(5.5,6.6),(7.7,8.8)])
>>> arr
array([[ 1.1,  2.2],
       [ 3.3,  4.4],
       [ 5.5,  6.6],
       [ 7.7,  8.8]])
>>> arr[:,0]
array([ 1.1,  3.3,  5.5,  7.7])

所以效果很好,绝对适合我的需求。但是,当我尝试从 pandas 数据框创建一个 numpy 数组时,就会出现问题。在这种情况下,上述解决方案会因各种错误而失败。例如:

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'other':[0,0,0,1,1],'point':[(1.1,2.2),(3.3,4.4),(5.5,6.6),(7.7,8.8),(9.9,0.0)]})
>>> df
   other       point
0      0  (1.1, 2.2)
1      0  (3.3, 4.4)
2      0  (5.5, 6.6)
3      1  (7.7, 8.8)
4      1  (9.9, 0.0)
>>> arr2 = np.array(df['point'])
>>> arr2
array([(1.1, 2.2), (3.3, 4.4), (5.5, 6.6), (7.7, 8.8), (9.9, 0.0)], dtype=object)
>>> arr2[:,0]
IndexError: too many indices for array

或者:

>>> arr2 = np.array([df['point']])
>>> arr2
array([[[1.1, 2.2],
        [3.3, 4.4],
        [5.5, 6.6],
        [7.7, 8.8],
        [9.9, 0.0]]], dtype=object)
>>> arr2[:,0]
array([[1.1, 2.2]], dtype=object)   # Which is not what I want!

当我将数据从 pandas 数据帧传输到 numpy 数组时,似乎出了点问题 - 但我不知道是什么。如有任何建议,我们将不胜感激。

【问题讨论】:

    标签: python arrays numpy pandas dataframe


    【解决方案1】:

    从您的数据框开始,我可以提取 (5,2) 数组:

    In [68]: df=pandas.DataFrame({'other':[0,0,0,1,1],'point':[(1.1,2.2),(3.3,4.4),(5.5,6.6),(7.7,8.8),(9.9,0.0)]})
    
    In [69]: np.array(df['point'].tolist())
    Out[69]: 
    array([[ 1.1,  2.2],
           [ 3.3,  4.4],
           [ 5.5,  6.6],
           [ 7.7,  8.8],
           [ 9.9,  0. ]])
    

    df['point'] 是熊猫系列。

    df['point'].values 返回一个形状为(5,) 和dtype 为object 的数组。我

    array([(1.1, 2.2), (3.3, 4.4), (5.5, 6.6), (7.7, 8.8), (9.9, 0.0)], dtype=object)
    

    实际上,它是一个元组数组。真正的元组,而不是结构化数组 tuple-look-a-likes。该数组实际上包含指向元组的指针,这些指针位于内存中的其他位置。它的形状是(5,) - 它是一个一维数组,因此尝试像二维一样进行索引会给您“太多”错误。 np.array([df['point']]) 只是将其包装在另一个维度中,而没有解决基本的对象 dtype 问题。

    tolist() 将其转换为元组列表,您可以从中构建二维数组。

    将数据从对象数组复制到 n-d 数组并非易事,而且总是需要某种形式的复制。数据缓冲区完全不同,所以像 astype 这样的东西不起作用。

    【讨论】:

    • 非常清晰简洁的解释 - 非常感谢。
    【解决方案2】:
    import numpy as np
    import pandas as pd
    df = pd.DataFrame({'other':[0,0,0,1,1],'point':[(1.1,2.2),(3.3,4.4),(5.5,6.6),(7.7,8.8),(9.9,0.0)]})
    array = df['point'].apply(lambda x: x[0]).values
    array
    # array([ 1.1,  3.3,  5.5,  7.7,  9.9])
    

    【讨论】:

    • 感谢您的解决方案。那肯定会产生所需的输出。但是,它并没有真正解决为什么将数据从数据帧导入 numpy 数组不起作用的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多