Ответ 1
Самый быстрый способ, который также сохраняет dtypes
, заключается в следующем:
for col in df.columns:
df[col].values[:] = 0
Это напрямую записывает в базовый массив numy каждого столбца. Я сомневаюсь, что любой другой метод будет быстрее, чем этот, поскольку он не выделяет дополнительной памяти и не проходит через обработку панд dtype
. Вы также можете использовать np.issubdtype
только для обнуления числовых столбцов. Это, вероятно, то, что вам нужно, если у вас смешанный dtype
DataFrame, но, конечно, в этом нет необходимости, если ваш DataFrame уже полностью числовой.
for col in df.columns:
if np.issubdtype(df[col].dtype, np.number):
df[col].values[:] = 0
Для небольших DataFrames проверка подтипа несколько затратна. Однако стоимость обнуления нечислового столбца является существенной, поэтому, если вы не уверены, является ли ваш DataFrame полностью числовым, вам следует включить проверку issubdtype
.
Сроки сравнения
Настройка
import pandas as pd
import numpy as np
def make_df(n, only_numeric):
series = [
pd.Series(range(n), name="int", dtype=int),
pd.Series(range(n), name="float", dtype=float),
]
if only_numeric:
series.extend(
[
pd.Series(range(n, 2 * n), name="int2", dtype=int),
pd.Series(range(n, 2 * n), name="float2", dtype=float),
]
)
else:
series.extend(
[
pd.date_range(start="1970-1-1", freq="T", periods=n, name="dt")
.to_series()
.reset_index(drop=True),
pd.Series(
[chr((i % 26) + 65) for i in range(n)],
name="string",
dtype="object",
),
]
)
return pd.concat(series, axis=1)
>>> make_df(5, True)
int float int2 float2
0 0 0.0 5 5.0
1 1 1.0 6 6.0
2 2 2.0 7 7.0
3 3 3.0 8 8.0
4 4 4.0 9 9.0
>>> make_df(5, False)
int float dt string
0 0 0.0 1970-01-01 00:00:00 A
1 1 1.0 1970-01-01 00:01:00 B
2 2 2.0 1970-01-01 00:02:00 C
3 3 3.0 1970-01-01 00:03:00 D
4 4 4.0 1970-01-01 00:04:00 E
Маленький DataFrame
n = 10_000
# Numeric df, no issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
df[col].values[:] = 0
36.1 µs ± 510 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# Numeric df, yes issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
if np.issubdtype(df[col].dtype, np.number):
df[col].values[:] = 0
53 µs ± 645 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# Non-numeric df, no issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
df[col].values[:] = 0
113 µs ± 391 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# Non-numeric df, yes issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
if np.issubdtype(df[col].dtype, np.number):
df[col].values[:] = 0
39.4 µs ± 1.91 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Большой фрейм данных
n = 10_000_000
# Numeric df, no issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
df[col].values[:] = 0
38.7 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Numeric df, yes issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
if np.issubdtype(df[col].dtype, np.number):
df[col].values[:] = 0
39.1 ms ± 556 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Non-numeric df, no issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
df[col].values[:] = 0
99.5 ms ± 748 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Non-numeric df, yes issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
if np.issubdtype(df[col].dtype, np.number):
df[col].values[:] = 0
17.8 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Ранее я предлагал ответ ниже, но теперь я считаю его вредным - он значительно медленнее, чем приведенные выше, и его сложнее рассуждать. Его единственное преимущество - писать приятнее.
Самый чистый способ - использовать голое двоеточие для ссылки на весь dataframe.
df[:] = 0
К сожалению, ситуация
dtype
немного размыта, потому что каждый столбец в результирующем кадре данных будет иметь тот жеdtype
. Если каждый столбецdf
изначально былfloat
, новыйdtypes
все равно будетfloat
. Но если один столбец былint
илиobject
, кажется, что новыйdtypes
будет всеint
.