Устаревайте ваше использование values
и as_matrix()
!
В pandas v0.24.0 появились два новых метода получения массивов NumPy из объектов pandas:
to_numpy()
, который определен Index
, Series,
и DataFrame
объекты, и
array
, Который определяется на Index
и Series
только объекты.
Если вы посетите документацию v0.24 для .values
, вы увидите большое красное предупреждение, которое гласит:
Предупреждение: мы рекомендуем использовать DataFrame.to_numpy()
вместо этого.
См. Этот раздел примечаний к выпуску v0.24.0 и этот ответ для получения дополнительной информации.
На пути к лучшей согласованности: to_numpy()
В духе лучшей согласованности по всему API to_numpy
был введен новый метод для извлечения базового массива NumPy из DataFrames.
# Setup.
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])
df.to_numpy()
array([[1, 4],
[2, 5],
[3, 6]])
Как упоминалось выше, этот метод также определен для объектов 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
a -1 4
b 2 5
c 3 6
Если вам нужна копия, используйте to_numpy(copy=True
).
pandas> = 1.0 обновление для ExtensionTypes
Если вы используете 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
# Right
a.to_numpy(dtype='float', na_value=np.nan)
# array([ 1., 2., nan])
Это называется в документах .
Если вам нужно dtypes
...
Как показано в другом ответе, DataFrame.to_records
это хороший способ сделать это.
df.to_records()
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])
Это не может быть сделано to_numpy
, к сожалению. Однако в качестве альтернативы вы можете использовать np.rec.fromrecords
:
v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<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())
11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Обоснование добавления нового метода
to_numpy()
(в дополнение к array
) был добавлен в результате обсуждений в рамках двух выпусков GitHub GH19954 и GH23623 .
В частности, в документах упоминается обоснование:
[...] с .values
этим было неясно, будет ли возвращаемое значение фактическим массивом, некоторым его преобразованием или одним из пользовательских массивов панд (например Categorical
). Например, с PeriodIndex
, каждый раз .values
генерирует новые ndarray
объекты периода. [...]
to_numpy
стремиться улучшить согласованность API, что является важным шагом в правильном направлении. .values
не будет объявлено устаревшим в текущей версии, но я ожидаю, что это может произойти в какой-то момент в будущем, поэтому я призываю пользователей перейти на более новый API, как только вы сможете.
Критика других решений
DataFrame.values
имеет противоречивое поведение, как уже отмечалось.
DataFrame.get_values()
это просто обертка вокруг DataFrame.values
, так что все сказанное выше применимо.
DataFrame.as_matrix()
устарел сейчас, не используйте!