df.to_numpy()
比 好df.values
,这就是为什么。*
是时候弃用values
and了as_matrix()
。
pandasv0.24.0
引入了两种从 pandas 对象获取 NumPy 数组的新方法:
to_numpy()
, 定义在Index
, Series
, 和DataFrame
对象上, 和
array
Index
, 仅在和Series
对象上定义。
如果您访问 v0.24 文档.values
,您将看到一个大红色警告,上面写着:
警告:我们建议DataFrame.to_numpy()
改用。
请参阅v0.24.0 发行说明的这一部分,以及此答案以获取更多信息。
* -to_numpy()
对于需要在未来的多个版本中可靠运行的任何生产代码,我推荐的方法。但是,如果您只是在 jupyter 或终端中制作暂存器,那么使用.values
来节省几毫秒的输入时间是一个允许的例外。您可以随时添加适合 n 完成以后。
本着在整个 API 中保持更好一致性的精神,to_numpy
引入了一种新方法来从 DataFrames 中提取底层 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]])
如上所述,此方法也定义在Index
和Series
对象上(参见此处)。
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)
.
扩展类型的熊猫 >= 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])
这在 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下讨论的结果。
具体来说,文档提到了理由:
[...].values
不清楚返回的值是实际数组、它的一些转换,还是 pandas 自定义数组之一(如Categorical
)。例如,使用PeriodIndex
,每次都会.values
生成一个新的 period 对象。ndarray
[...]
to_numpy
旨在提高 API 的一致性,这是朝着正确方向迈出的重要一步。.values
在当前版本中不会被弃用,但我预计这可能会在未来的某个时候发生,所以我会敦促用户尽快迁移到更新的 API。
对其他解决方案的批评
DataFrame.values
如前所述,具有不一致的行为。
DataFrame.get_values()
只是一个包装器DataFrame.values
,所以上面所说的一切都适用。
DataFrame.as_matrix()
现已弃用,请勿使用!