Как ускорить эту задачу в Python - PullRequest
1 голос
/ 09 января 2020

У меня большой Pandas фрейм данных, 24'000'000 строк × 6 столбцов плюс индекс. Мне нужно прочитать целое число в столбце 1 (то есть = 1 или 2), а затем заставить значение в столбце 3 быть отрицательным, если столбец 1 = 1, или положительным, если = 2. Я использую следующий код в блокноте Jupyter:

for i in range(1000):
    if df.iloc[i,1] == 1:
        df.iloc[i,3] = abs(df.iloc[i,3])*(-1)
    if df.iloc[i,1] == 2:
        df.iloc[i,3] = abs(df.iloc[i,3])

Приведенный выше код занимает 2 минуты 30 секунд c для запуска только для 1000 строк. Для 24M строк потребуется 41 день!

Что-то не так. Код работает в Jupyter Notebook / Chrome / Windows на довольно высоком конце P C.

. Кадр данных Pandas создается с помощью pd.read_csv, а затем сортируется и индексируется следующим образом:

df.sort_values(by = "My_time_stamp", ascending=True,inplace = True)
df = df.reset_index(drop=True)

Создание и сортировка кадра данных занимает всего несколько секунд. У меня есть другие вычисления для этого кадра данных, поэтому я должен четко понимать, что я делаю неправильно.

Ответы [ 4 ]

3 голосов
/ 09 января 2020

np.where

a = np.where(df.iloc[:, 1].to_numpy() == 1, -1, 1)
b = np.abs(df.iloc[:, 3].to_numpy())
df.iloc[:, 3] = a * b
2 голосов
/ 09 января 2020

Векторизация:

df.iloc[:, 3] = df.iloc[:, 3].abs() * (2 * (df.iloc[:, 1] != 1) - 1)

Объяснение:

Рассматривается как int, логическая серия df.iloc[:, 1] != 1 преобразуется в единицы и нули. Умноженный на 2, он получает двойки и нули. После вычитания единицы он получает -1, где первый столбец равен 1, а 1 в противном случае Наконец, он умножается на абсолютное значение третьего столбца, который вводит знак.

Векторизация обычно обеспечивает порядок или ускорение в два раза по сравнению с циклами for.

1 голос
/ 09 января 2020

Использование

df.iloc[:,3] = df.iloc[:,3].abs().mul( df.iloc[:,-1].map({2:1,1:-1}) )
0 голосов
/ 09 января 2020

Другой способ сделать это:

import pandas as pd

Взять пример набора данных:

df = pd.DataFrame({'x1':[1,2,1,2], 'x2':[4,8,1,2]})

Создать новый столбец, кодовые значения которого равны -1 и +1:

df['nx1'] = df['x1'].replace({1:-1, 2:1})

Умножить по столбцам:

df['nx1'] * df['x2']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...