Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何有效地从数据帧中获取列子集的numpy数组? 动机_Python_Pandas_Numpy - Fatal编程技术网

Python 如何有效地从数据帧中获取列子集的numpy数组? 动机

Python 如何有效地从数据帧中获取列子集的numpy数组? 动机,python,pandas,numpy,Python,Pandas,Numpy,我经常回答一些问题,其中我提倡将数据帧值转换为底层numpy数组,以便更快地进行计算。然而,这样做有一些警告,有些方法比其他方法更好 我将提供我自己的答案,努力回馈社区。我希望你们觉得它有用 问题 考虑数据文件 DF df = pd.DataFrame(dict(A=[1, 2, 3], B=list('xyz'), C=[9, 8, 7], D=[4, 5, 6])) print(df) A B C D 0 1 x 9 4 1 2 y 8 5 2 3 z

我经常回答一些问题,其中我提倡将数据帧值转换为底层numpy数组,以便更快地进行计算。然而,这样做有一些警告,有些方法比其他方法更好

我将提供我自己的答案,努力回馈社区。我希望你们觉得它有用

问题
考虑数据文件<代码> DF

df = pd.DataFrame(dict(A=[1, 2, 3], B=list('xyz'), C=[9, 8, 7], D=[4, 5, 6]))
print(df)

   A  B  C  D
0  1  x  9  4
1  2  y  8  5
2  3  z  7  6
使用
d类型

print(df.dtypes)

A     int64
B    object
C     int64
D     int64
dtype: object
我想创建一个numpy数组
a
,它由
a
C
列中的值组成。假设可能有很多列,我的目标是两个特定的列
A
C

我尝试过的

我可以做到:

df[['A', 'C']].values

array([[1, 9],
       [2, 8],
       [3, 7]])
这是准确的

不过,我可以用numpy做得更快

p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p]

array([[1, 9],
       [2, 8],
       [3, 7]], dtype=object)
这是更快,但不准确。注意
dtype=object
。我需要整数

p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p].astype(int)

array([[1, 9],
       [2, 8],
       [3, 7]])
现在这是正确的,但我可能不知道我有所有的整数

定时

# Clear and accurate, but slower
%%timeit 
df[['A', 'C']].values
1000 loops, best of 3: 347 µs per loop

# Not accurate, but close and fast
%%timeit 
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p]
10000 loops, best of 3: 59.2 µs per loop

# Accurate for this test case and fast, needs to be more generalized.
%%timeit 
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p].astype(int)
10000 loops, best of 3: 59.3 µs per loop

pandas
values
属性中为整个数据帧存储单个数组。在数据帧上调用
values
属性时,它从存储的底层对象(即
pd.Series
对象)构建数组。将数据帧视为
pd.Series
pd.Series
,其中每列都是数据帧包含的
pd.Series
,这很有用。每列可以有一个不同于其他列的
dtype
。这就是为什么数据帧如此有用的部分原因。但是,numpy数组必须有一种类型。当我们在数据帧上调用
values
属性时,它会转到每一列,从每个
values
属性中提取数据,并将它们拼凑在一起。如果各列的数据类型不一致,则结果数组的
dtype
将被强制为
object

选项1
缓慢但准确

之所以速度慢,是因为您要求pandas为您构建一个新的数据框
df[['a','C']]
,然后通过点击新数据框的每个列的“值”属性来构建数组
a

选项2
找到列位置,然后切片

这更好,因为我们只构建值数组,而不重建新的数据帧。我相信我们得到的数组具有一致的数据类型。如果需要上档,我在这里处理得不好

选项3
我的首选方法
仅访问我关心的列的值

这将pandas dataframe用作
pd.Series
的容器,在该容器中,我只访问我关心的列的
属性。然后,我从这些数组中构建一个新数组。如果需要解决铸造问题,numpy将处理它


所有方法都产生相同的结果

array([[1, 9],
       [2, 8],
       [3, 7]])

定时
小数据

大数据

试试这个:

np.array(zip(df['A'].values, df['C'].values))
时间:

%%timeit
np.array(zip(df['A'].values, df['C'].values))
最慢的跑步比最快的跑长5.51倍。这可能意味着正在缓存中间结果。
10000个循环,最好3个:每个循环17.8µs

pd系列是否使用numpy数组存储其值?@hpaulj老实说,我不能确定。但我很确定这是肯定的。指的是我无法跟踪的
\u data
属性。但是显示了被分配了@hpaulj的
data
属性,这是一个numpy数组。。。排序:-)
array([[1, 9],
       [2, 8],
       [3, 7]])
%%timeit 
a = df[['A', 'C']].values
1000 loops, best of 3: 338 µs per loop

%%timeit 
c = ['A', 'C']
p = [df.columns.get_loc(i) for i in c]
a = df.values[:, p].astype(df.dtypes[c[0]])
10000 loops, best of 3: 166 µs per loop

%timeit np.column_stack([df[col].values for col in ['A', 'C']])
The slowest run took 7.36 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 8.97 µs per loop
df = pd.concat(
    [df.join(pd.DataFrame(
                np.random.randint(10, size=(3, 22)),
                columns=list(ascii_uppercase[4:])
            ))] * 10000, ignore_index=True
)


%%timeit 
a = df[['A', 'C']].values
The slowest run took 23.28 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 371 µs per loop
In [305]:

%%timeit 
c = ['A', 'C']
p = [df.columns.get_loc(i) for i in c]
a = df.values[:, p].astype(df.dtypes[c[0]])
100 loops, best of 3: 9.62 ms per loop

%timeit np.column_stack([df[col].values for col in ['A', 'C']])
The slowest run took 6.66 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 55.6 µs per loop
np.array(zip(df['A'].values, df['C'].values))
%%timeit
np.array(zip(df['A'].values, df['C'].values))