gpt4 book ai didi

python - 将 pandas 数据框转换为 NumPy 数组

转载 作者:IT老高 更新时间:2023-10-28 12:05:53 25 4
gpt4 key购买 nike

如何将 pandas 数据帧转换为 NumPy 数组?

数据帧:

import numpy as np
import pandas as pd

index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')

给予

label   A    B    C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN

我想将其转换为 NumPy 数组,如下所示:

array([[ nan,  0.2,  nan],
[ nan, nan, 0.5],
[ nan, 0.2, 0.5],
[ 0.1, 0.2, nan],
[ 0.1, 0.2, 0.5],
[ 0.1, nan, 0.5],
[ 0.1, nan, nan]])

另外,是否可以像这样保留数据类型?

array([[ 1, nan,  0.2,  nan],
[ 2, nan, nan, 0.5],
[ 3, nan, 0.2, 0.5],
[ 4, 0.1, 0.2, nan],
[ 5, 0.1, 0.2, 0.5],
[ 6, 0.1, nan, 0.5],
[ 7, 0.1, nan, nan]],
dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])

最佳答案

使用 df.to_numpy()

它比 df.values 更好,原因如下。*

是时候弃用valuesas_matrix()了。

pandas v0.24.0 引入了两种从 pandas 对象获取 NumPy 数组的新方法:

  1. to_numpy(),定义在IndexSeriesDataFrame 对象,以及
  2. array,仅在 IndexSeries 对象上定义。

如果您访问 .values 的 v0.24 文档,你会看到一个大红色警告,上面写着:

Warning: We recommend using DataFrame.to_numpy() instead.

this section of the v0.24.0 release notes , 和 this answer了解更多信息。

* - to_numpy() 是我推荐的任何生产代码的方法,这些生产代码需要在未来的多个版本中可靠运行。但是,如果您只是在 jupyter 或终端中制作暂存器,则使用 .values 来节省几毫秒的输入时间是允许的异常(exception)。您可以随时添加适合 n 完成。



实现更好的一致性:to_numpy()

本着提高整个 API 一致性的精神,引入了一种新方法 to_numpy,用于从 DataFrame 中提取底层 NumPy 数组。

# Setup
df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]},
index=['a', 'b', 'c'])

# Convert the entire DataFrame
df.to_numpy()
# array([[1, 4, 7],
# [2, 5, 8],
# [3, 6, 9]])

# Convert specific columns
df[['A', 'C']].to_numpy()
# array([[1, 7],
# [2, 8],
# [3, 9]])

如上所述,此方法也定义在 IndexSeries 对象上(参见 here)。

df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)

df['A'].to_numpy()
# array([1, 2, 3])

默认情况下,会返回一个 View ,因此所做的任何修改都会影响原始 View 。

v = df.to_numpy()
v[0, 0] = -1

df
A B C
a -1 4 7
b 2 5 8
c 3 6 9

如果您需要副本,请使用 to_numpy(copy=True)


pandas >= ExtensionTypes 1.0 更新

如果您使用的是 pandas 1.x,那么您可能会更多地处理扩展类型。您必须更加小心这些扩展类型是否正确转换。

a = pd.array([1, 2, None], dtype="Int64")                                  
a

<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64

# Wrong
a.to_numpy()
# array([1, 2, <NA>], dtype=object) # yuck, objects

# Correct
a.to_numpy(dtype='float', na_value=np.nan)
# array([ 1., 2., nan])

# Also correct
a.to_numpy(dtype='int', na_value=-1)
# array([ 1, 2, -1])

这是called out in the docs .


如果您需要结果中的 dtypes...

如另一个答案所示,DataFrame.to_records是一个很好的方法。

df.to_records()
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])

不幸的是,这不能用 to_numpy 完成。但是,作为替代方案,您可以使用 np.rec.fromrecords:

v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])

性能方面,几乎相同(实际上,使用 rec.fromrecords 会快一点)。

df2 = pd.concat([df] * 10000)

%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())

12.9 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.56 ms ± 291 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


添加新方法的理由

to_numpy()(除了 array)是在两个 GitHub 问题 GH19954 下讨论的结果。和 GH23623 .

具体来说,文档提到了理由:

[...] with .values it was unclear whether the returned value would be theactual array, some transformation of it, or one of pandas customarrays (like Categorical). For example, with PeriodIndex, .valuesgenerates a new ndarray of period objects each time. [...]

to_numpy 旨在提高 API 的一致性,这是朝着正确方向迈出的重要一步。 .values 在当前版本中不会被弃用,但我预计这可能会在未来的某个时候发生,所以我会敦促用户尽快迁移到更新的 API。



对其他解决方案的批评

DataFrame.values 行为不一致,如前所述。

DataFrame.get_values()quietly removed in v1.0并且之前在 v0.25 中已弃用。在此之前,它只是 DataFrame.values 的一个包装器,所以上面所说的一切都适用。

DataFrame.as_matrix() 在 v1.0 中被移除,之前在 v0.23 中被弃用。请使用!

关于python - 将 pandas 数据框转换为 NumPy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13187778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com