将 pandas 数据框转换为 NumPy 数组

新手上路,请多包涵

如何将 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')])

原文由 Mister Nobody 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
1 个回答

使用 df.to_numpy()

它比 df.values 更好,这就是原因。 *

是时候弃用 valuesas_matrix()

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

  1. to_numpy() SeriesIndex DataFrame
  2. array ,仅在 IndexSeries 对象上定义。

如果您访问 .values 的 v0.24 文档,您将看到一个红色的大警告:

警告:我们建议改用 DataFrame.to_numpy()

有关详细信息,请参阅 v0.24.0 发行说明的这一部分此答案

\* - to_numpy() 是我推荐的方法,用于任何需要在未来的许多版本中可靠运行的生产代码。但是,如果您只是在 jupyter 或终端中制作便签本,使用 .values 来节省几毫秒的输入是一个允许的例外。您可以随时添加 fit n finish。



实现更好的一致性: 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 对象上定义(参见 此处)。

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

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

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

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

在文档中被调用


如果您需要结果中的 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 之外)是作为 GH19954GH23623 两个 GitHub 问题下讨论的结果添加的。

具体来说, 文档 提到了基本原理:

[…] .values 不清楚返回值是实际数组、它的某些转换还是 pandas 自定义数组之一(如 Categorical )。例如,对于 PeriodIndex.values 生成一个新的 ndarray 周期对象。 […]

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



对其他解决方案的批评

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

DataFrame.get_values() 在 v1.0 中悄悄删除, 之前在 v0.25 中弃用。在此之前,它只是 DataFrame.values 的包装器,所以上面所说的一切都适用。

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

原文由 cs95 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题