访问numpy数组元组中的第一项

时间:2015-03-25 00:03:07

标签: python arrays numpy pandas dataframe

我有一个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数组时似乎出现了问题 - 但我不知道是什么。我们将非常感激地收到任何建议。

2 个答案:

答案 0 :(得分:2)

从您的数据框开始,我可以使用以下内容提取(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)

实际上,它是一组元组。真正的元组,而不是结构化数组元组看起来像。该数组实际上包含指向元组的指针,这些指针位于内存中。它的形状是(5,) - 它是一个1d数组,因此尝试索引就好像它是2d会给你“太多”错误。 np.array([df['point']])只是将其包含在另一个维度中,而不解决基本对象dtype问题。

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

将数据从对象数组复制到n-d数组并非易事,而且总是需要某种复制。数据缓冲区完全不同,因此astype之类的东西不起作用。

答案 1 :(得分:0)

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])