Лучшая практика (эффективность) манипулирования данными pandas больших данных - PullRequest
0 голосов
/ 13 февраля 2020

Я имею дело с большими наборами данных, и я хотел бы спросить, как лучше изменить некоторые записи pandas фрейма данных df

Вот мой код:

mask = df.P2I.values > c_th
df.loc[mask, 'P1I'] = df.P1I - c_offset
df.loc[mask, 'P3I'] = df.P3I - c_offset
df.loc[mask, 'P2I'] = df.P2I - c_offset
  1. Есть ли способ получить доступ к этим строкам-столбцам непосредственно в одном вызове и выполнить три операции в целом?
  2. Должен ли я вызвать .values для фрейма данных, чтобы иметь непрерывное распределение памяти сделать вычитание?

Я не могу измерить производительность, поэтому и спрашиваю. Спасибо, ребята

1 Ответ

1 голос
/ 13 февраля 2020

Вы можете сделать что-то подобное в вашем случае:

df.loc[mask, ['P1I', 'P2I', 'P3I']] -= c_offset

Вы также можете использовать различные смещения для каждого столбца, если вам нужно, например, (с точки зрения производительности это выглядит довольно похоже на первый):

df.loc[mask, ['P1I', 'P2I', 'P3I']] -= [ c_offset_1, c_offset_2, c_offset_3 ]

Однако, если производительность имеет решающее значение, кажется, что лучшие варианты действительно используют формат numpy. Вероятно, если ваш «математический спор» больше, чем одно вычитание, это похоже на go:

df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset

Примечание : OP проверил этот подход в своем наборе данных, и упомянул, что это было на самом деле медленнее, чем просто использование предыдущего. Пытался повторить это, но мой компьютер чуть не сломался, прежде чем я смог ...

Некоторые моменты времени я взял, сравнивая различные подходы:

import pandas as pd
import numpy as np

df = pd.DataFrame({ "P1I": np.random.rand(1000000), 
                    "P2I": np.random.rand(1000000), 
                    "P3I": np.random.rand(1000000) })

c_th = 0.5
c_offset = -1

mask = df.P2I > c_th
%timeit df.loc[ mask, "P1I" ] = df.loc[ mask , "P1I" ] - c_offset; df.loc[ mask, "P2I" ] = df.loc[ mask , "P2I" ] - c_offset; df.loc[ mask, "P3I" ] = df.loc[ mask , "P3I" ] - c_offset
# 77.9 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= c_offset
# 59.3 ms ± 1.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= [ c_offset, c_offset, c_offset ]
# 59.5 ms ± 3.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset
# 43.6 ms ± 553 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...