Как назначить значение для строк, которые находятся между двумя строками с определенной строкой в ​​столбце в кадре данных? - PullRequest
2 голосов
/ 15 октября 2019

У меня есть фрейм данных с временным рядом, где в одном столбце есть строки: Normal Value и Wrong Value. Я хотел бы найти все строки, которые находятся между строк с Wrong Value и назначить им 0 для нового столбца. Строки, которые имеют Normal Value и не находятся между строками с Wrong Value, должны иметь значение 1. Столбец Value представляет высокие пики во временных рядах.

Пример кадра данных:

>>> df = pd.DataFrame({'Date': ['2019-01-01','2019-01-02','2019-01-03','2019-01-04','2019-01-05','2019-01-06','2019-01-07','2019-01-08','2019-01-09', '2019-01-10'],
...                    'Value': [-0.011295, -0.013431, 580944.426061, 0.000000, 0.000000, -0.999998, 0.000000, 0.000000, 712327.147257, -0.999999],
...                    'String': ['Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Wrong Value']})
>>> df
         Date          Value        String
0  2019-01-01      -0.011295  Normal Value
1  2019-01-02      -0.013431  Normal Value
2  2019-01-03  580944.426061   Wrong Value
3  2019-01-04       0.000000  Normal Value
4  2019-01-05       0.000000  Normal Value
5  2019-01-06      -0.999998   Wrong Value
6  2019-01-07       0.000000  Normal Value
7  2019-01-08       0.000000  Normal Value
8  2019-01-09  712327.147257   Wrong Value
9  2019-01-10      -0.999999   Wrong Value

Ожидаемый результат:

>>> df = pd.DataFrame({'Date': ['2019-01-01','2019-01-02','2019-01-03','2019-01-04','2019-01-05','2019-01-06','2019-01-07','2019-01-08','2019-01-09', '2019-01-10'],
...                    'Value': [-0.011295, -0.013431, 580944.426061, 0.000000, 0.000000, -0.999998, 0.000000, 0.000000, 712327.147257, -0.999999],
...                    'String': ['Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Wrong Value'],
...                    'Expected Value': [1, 1, 0, 0, 0, 0, 1, 1, 0, 0]})
>>> df
         Date          Value        String  Expected Value
0  2019-01-01      -0.011295  Normal Value               1
1  2019-01-02      -0.013431  Normal Value               1
2  2019-01-03  580944.426061   Wrong Value               0
3  2019-01-04       0.000000  Normal Value               0
4  2019-01-05       0.000000  Normal Value               0
5  2019-01-06      -0.999998   Wrong Value               0
6  2019-01-07       0.000000  Normal Value               1
7  2019-01-08       0.000000  Normal Value               1
8  2019-01-09  712327.147257   Wrong Value               0
9  2019-01-10      -0.999999   Wrong Value               0

Ответы [ 3 ]

0 голосов
/ 15 октября 2019

есть несколько функций pandas, которые работают в смежных строках: например, Series.diff или Series.pct_change или DataFrame.shift, но я бы решил эту в основном с помощью цикла и предложения if (или тривиального конечного автомата с состояниями между или нетмежду.).

import pandas as pd

df = pd.DataFrame({'Date': ['2019-01-01','2019-01-02','2019-01-03','2019-01-04','2019-01-05','2019-01-06','2019-01-07','2019-01-08','2019-01-09', '2019-01-10'],
                   'Value': [-0.011295, -0.013431, 580944.426061, 0.000000, 0.000000, -0.999998, 0.000000, 0.000000, 712327.147257, -0.999999],
                   'String': ['Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Wrong Value']})

state_machine = {(0,"Normal Value"): (0,1),
                 (0,"Wrong Value") : (1,0),
                 (1,"Normal Value"): (1,0),
                 (1,"Wrong Value") : (0,0),
                }
state=0
expected_values = []
for s in df['String']:
    state, expected = state_machine[state,s]
    expected_values.append(expected)
df['Expected Value'] = expected_values

print(df)

 Date          Value        String  Expected Value
0  2019-01-01      -0.011295  Normal Value               1
1  2019-01-02      -0.013431  Normal Value               1
2  2019-01-03  580944.426061   Wrong Value               0
3  2019-01-04       0.000000  Normal Value               0
4  2019-01-05       0.000000  Normal Value               0
5  2019-01-06      -0.999998   Wrong Value               0
6  2019-01-07       0.000000  Normal Value               1
7  2019-01-08       0.000000  Normal Value               1
8  2019-01-09  712327.147257   Wrong Value               0
9  2019-01-10      -0.999999   Wrong Value               0
0 голосов
/ 15 октября 2019

Код Python:

import pandas as pd

def condition(x):
  if x == 'Wrong Value':
    return 0
  return 1

dict = {'Date': ['2019-01-01','2019-01-02','2019-01-03','2019-01-04','2019-01-05','2019-01-06','2019-01-07','2019-01-08','2019-01-09', '2019-01-10'],
        'Value': [-0.011295, -0.013431, 580944.426061, 0.000000, 0.000000, -0.999998, 0.000000, 0.000000, 712327.147257, -0.999999],
        'String': ['Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Normal Value', 'Normal Value', 'Wrong Value', 'Wrong Value']
       }
df = pd.DataFrame(dict)

new_df = df['String'].apply(condition)
idx = df.index[new_df < 1]

for i in range(0,len(idx),2):
  if idx[i+1] - idx[i] > 1:
    new_df.loc[idx[i]:idx[i+1]] = 0

df['Expected Value'] = new_df
print (df)

Выход:

 Date          Value        String  Expected Value
0  2019-01-01      -0.011295  Normal Value               1
1  2019-01-02      -0.013431  Normal Value               1
2  2019-01-03  580944.426061   Wrong Value               0
3  2019-01-04       0.000000  Normal Value               0
4  2019-01-05       0.000000  Normal Value               0
5  2019-01-06      -0.999998   Wrong Value               0
6  2019-01-07       0.000000  Normal Value               1
7  2019-01-08       0.000000  Normal Value               1
8  2019-01-09  712327.147257   Wrong Value               0
9  2019-01-10      -0.999999   Wrong Value               0
0 голосов
/ 15 октября 2019

По сути, вы хотите преобразовать этот список [1,1,0,1,1,0,1,1,0,0,...] (1 - нормальное, а 0 - неправильные значения) в: [1,1,0,0,0,0,1,1,0,0,...]

Простой цикл for может выполнить работу:

a = []
is_wrong = 0
for value in df['String'].values:
    if is_wrong == 0:
        if value == 'Normal Value':
            a.append(1)
        else:
            a.append(0)
            is_wrong = 1
    else:
        if value == 'Normal Value':
            a.append(0)
        else:
            a.append(0)
            is_wrong = 0
df['Expected Value'] = a

(может быть) более элегантный способ может быть:

a = []
is_wrong = False # store the current state
for value in df['String'].map({'Normal Value':True,'Wrong Value':False}).values:
    a.append(value and not is_wrong) # check the current state and output value
    is_wrong = is_wrong if value else not is_wrong # change the state if needed
df['Expected Value'] = [int(x) for x in a]

в обоих случаях:

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