Устаревайте ваше использование 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()устарел сейчас, не используйте!