Как векторизовать функцию, которая использует элементы строки и столбца информационного кадра - PullRequest
0 голосов
/ 19 января 2020

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

Эта команда dataframe создаст пример того, что мне нужно:

df=pd.DataFrame([[0,0,0], [0,1,0], [0,0,0], [1,1,1], [0,1,1], [0,1,1], [0,0,0], [0,1,0], [0,1,0], [1,1,1], [1,1,1], [0,1,1], [0,1,1], [1,1,1], [0,1,1], [0,1,1], [0,0,0], [0,1,0]], columns=['input_1', 'input_2', 'output'])

Правила просты:

  • Если input_1 равен 1, вывод равен 1 (input_1 - это функция триггера)
  • вывод будет оставаться равным 1, пока input_2 также равен 1. (input_2 работает как функция памяти)
  • Для всех остальных вывод будет 0

Строки go в последовательности, как они происходят во времени, я имею в виду, выход строки 0 влияет на выход строки 1, выход строки 1 влияет на выход строки 2 и так далее. Таким образом, вывод зависит от input_1, input_2, но также и от его собственного предыдущего значения.

Я мог бы закодировать его в цикле по кадрам данных, вычисляя и присваивая значения, используя ilo c, но это мучительно медленно. Мне нужно выполнить это через тысячи строк для десятков тысяч фреймов данных, поэтому я ищу наиболее эффективный способ сделать это (желательно векторизацию). Это может быть numpy или другая известная вам библиотека / метод.

Я искал и нашел несколько вопросов о векторизации и циклическом переносе строк, но я все еще не понимаю, как использовать эти методы. Примеры вопросов: Как перебирать строки в DataFrame в Pandas? . Также этот, Какой самый эффективный способ l oop через кадры данных с pandas?

Я ценю вашу помощь

Ответы [ 2 ]

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

Если я вас правильно понял, вы хотите знать, как вычислить столбец output. Вы можете сделать, например:

df['output_2'] = (df['input_1'] + df['input_2']).replace(1, np.nan).ffill().replace(2, 1).astype(int)
print(df)

Отпечатки:

    input_1  input_2  output  output_2
0         0        0       0         0
1         0        1       0         0
2         0        0       0         0
3         1        1       1         1
4         0        1       1         1
5         0        1       1         1
6         0        0       0         0
7         0        1       0         0
8         0        1       0         0
9         1        1       1         1
10        1        1       1         1
11        0        1       1         1
12        0        1       1         1
13        1        1       1         1
14        0        1       1         1
15        0        1       1         1
16        0        0       0         0
17        0        1       0         0
1 голос
/ 19 января 2020

Как вы объяснили в обсуждении выше, у нас есть только два входа, загруженные с использованием pandas dataframe:

df=pd.DataFrame([[0,0], [0,1], [0,0], [1,1], [0,1], [0,1], [0,0], [0,1], [0,1], [1,1], [1,1], [0,1], [0,1], [1,1], [0,1], [0,1], [0,0], [0,1]], columns=['input_1', 'input_2'])

Мы должны создать выходные данные, используя следующие правила:

#1 if input_1 is one the output is one
#2 if both inputs is zero the output is zero
#3 if input_1 is zero and input_2 is one the output holds the previous value
#4 the initial output value is zero

для генерировать выходные данные, которые мы можем

  1. дублировать input_1 на выход
  2. обновить вывод предыдущим значением, если input_1 равен нулю, а input_2 равен единице

из-за правил выше нам не нужно обновлять первый вывод

df['output'] = df.input_1

for idx, row in df.iterrows():
   if (idx > 0) and (row.input_1 == 0) and (row.input_2 == 1):
       df.output[idx] = df.output[idx-1]

print(df)

Вывод:

>>> print(df)
    input_1  input_2  output
0         0        0       0
1         0        1       0
2         0        0       0
3         1        1       1
4         0        1       1
5         0        1       1
6         0        0       0
7         0        1       0
8         0        1       0
9         1        1       1
10        1        1       1
11        0        1       1
12        0        1       1
13        1        1       1
14        0        1       1
15        0        1       1
16        0        0       0
17        0        1       0

UPDATE1

Более быстрый способ Для этого нужно изменить формулу, предложенную @ Andrej

df['output_2'] = (df['input_1'] + df['input_2'] * 2).replace(2, np.nan).ffill().replace(3, 1).astype(int)

. Без модификации его формула создает неправильный вывод для входной комбинации [1, 0]. Он сохраняет предыдущий вывод вместо того, чтобы устанавливать его на 1.

UPDATE2

Это просто для сравнения результатов

df=pd.DataFrame([[0,0], [1,0], [0,1], [1,1], [0,1], [0,1], [0,0], [0,1], [0,1], [1,1], [1,1], [0,1], [0,1], [1,1], [0,1], [0,1], [0,0], [0,1]], columns=['input_1', 'input_2'])

df['output'] = df.input_1
for idx, row in df.iterrows():
   if (idx > 0) and (row.input_1 == 0) and (row.input_2 == 1):
       df.output[idx] = df.output[idx-1]

df['output_1'] = (df['input_1'] + df['input_2'] * 2).replace(2, np.nan).ffill().replace(3, 1).astype(int)
df['output_2'] = (df['input_1'] + df['input_2']).replace(1, np.nan).ffill().replace(2, 1).astype(int)
print(df)

Результаты:

>>> print(df)
    input_1  input_2  output  output_1  output_2
0         0        0       0         0         0
1         1        0       1         1         0
2         0        1       1         1         0
3         1        1       1         1         1
4         0        1       1         1         1
5         0        1       1         1         1
6         0        0       0         0         0
7         0        1       0         0         0
8         0        1       0         0         0
9         1        1       1         1         1
10        1        1       1         1         1
11        0        1       1         1         1
12        0        1       1         1         1
13        1        1       1         1         1
14        0        1       1         1         1
15        0        1       1         1         1
16        0        0       0         0         0
17        0        1       0         0         0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...