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