Как условно добавить элементы в серию в кадре данных - PullRequest
0 голосов
/ 21 июня 2019

У меня есть следующий фрейм данных df1 =

Index  Data Positon   Cell

0      220    12      Cell1 
1      256    33      Cell2
2      175    45      Cell2 
3      150    56      Cell1 
4      120    67      Cell2
5      200    77      Cell1 
6      235    79      Cell1 
7      270    83      Cell2 
8      325    87      Cell1 
9      190    91      Cell1 
10     235    95      Cell1

У меня есть другой фрейм данных с сообщениями df2 =

Index Message Position
0      msg1     31
1      msg2     45
2      release  54 
3      msg2     67
4      msg1     82

Я хочу добавить новый столбец в df1, который принимает одну из двух строк 'value_1' и value_2 'согласно следующему условию

  1. Любая позиция в df1 выше 0-й позиции в df2 (например, 31 в df2), value = value_1

  2. Если сообщение msg1, то value = value_2 только для строк ниже позиции msg1, т.е. df1['Position'] >= df2['Position'][df2.Message == 'msg1'], где df['Cell'] = Cell1. Это должно продолжаться, пока мы не приблизимся к df2.Message = 'Release'. (Проверка должна быть выполнена)

  3. Если сообщение msg2, то value = value_2 только для строк ниже позиции msg2, т.е. df1['Position'] >= df2['Position'][df2.Message == 'msg2'], где df['Cell']= Cell2. Это должно продолжаться, пока мы не приблизимся к df2.Message = 'Release'. (Проверка должна быть выполнена)

  4. Если сообщение выпущено, то value = value_1 до следующего сообщения в df2.Message независимо от df ['Cell']

  5. Если не выполнено ни одного из 1,2, 3 и 4, value = value_1

В двух словах

Когда обнаруживается сообщение, отличное от значения сообщения об освобождении = значение_2 для ячейки, соответствующей сообщению (Cell1 для msg1 и Cell2 для msg2), до тех пор, пока не будет обнаружено освобождение. После обнаружения освобождения значение = значение_1 до тех пор, пока не будет обнаружено следующее сообщение (msg1 или msg2).

попробовал следующее

df1 = pd.read_clipboard()
df1 = df1.rename(columns = {'Positon':'Position'}) 
df1 = df1.iloc[:,1:4]
df2 = pd.read_clipboard()
df2 = df2.iloc[:,1:3]
tmp = pd.concat([df2,df1], sort =False).sort_values(['Position']).reset_index(drop = True)
tmp['value'] = 'novalue'
tmp['value'][tmp.Position < df2.Position[0]] = 'value_1'
for i in range(len(tmp)):
    if tmp.Message[i] == 'release':
        tmp.value[i: tmp.Message[i+1:].first_valid_index()] = 'value_1'
    if tmp.Message[i] =='msg1':
        for j in range(len(tmp.index[i+1:])):
            if tmp.Message[j] =='release':
                tmp.value[i:j][tmp.Cell =='Cell1'] = 'value_2'
            else:
                tmp.value[i:][tmp.Cell =='Cell1'] = 'value_2'
    if tmp.Message[i] =='msg2':
        for j in range(len(tmp.index[i+1:])):
            if tmp.Message[j] =='release':
                tmp.value[i:j][tmp.Cell =='Cell2'] = 'value_2'
            else:
                tmp.value[i:][tmp.Cell =='Cell2'] = 'value_2'
result = tmp.loc[~tmp.Cell.isna(),:]
result.value[result.value == 'novalue'] = 'value_1'

Я застрял, делая это. В основном этот код показывает значения value_2 для позиций 77 и 79, что не должно происходить. Мне трудно понять это.

Ожидаемый результат должен быть примерно таким:

Index  Data Positon   Cell   Value

0      220    12      Cell1  value_1
1      256    33      Cell2  value_1
2      175    45      Cell2  value_2
3      150    56      Cell1  value_1
4      120    67      Cell2  value_2
5      200    77      Cell1  value_1
6      235    79      Cell1  value_1
7      270    83      Cell2  value_2
8      325    87      Cell1  value_2
9      190    91      Cell1  value_2
10     235    95      Cell1  value_2

Было бы здорово, если бы кто-то мог помочь

1 Ответ

0 голосов
/ 22 июня 2019

Вот решение!

df1 = pd.read_clipboard()
df1 = df1.rename(columns = {'Positon':'Position'}) 
df1 = df1.iloc[:,1:4]
df2 = pd.read_clipboard()
df2 = df2.iloc[:,1:3]
tmp = pd.concat([df2,df1], sort =False).sort_values(['Position']).reset_index(drop = True)
tmp['value'] = 'novalue'
tmp['value'][tmp.Position < df2.Position[0]] = 'value_1'
for i in range(len(tmp)):
    if tmp.Message[i] == 'release':
        tmp.value[i: tmp.Message[i+1:].first_valid_index()] = 'value_1'
    if tmp.Message[i] =='msg1':
        val = tmp.Message[i+1:][tmp.Message == 'release'].first_valid_index()
        tmp.value[i:val][tmp.Cell =='Cell1'] = 'value_2'
    if tmp.Message[i] =='msg2':
        val = tmp.Message[i+1:][tmp.Message == 'release'].first_valid_index()
        tmp.value[i:val][tmp.Cell =='Cell2'] = 'value_2'
result = tmp.loc[~tmp.Cell.isna(),:]
result.value[result.value == 'novalue'] = 'value_1'
...