Панды для создания условного столбца, выбрав несколько столбцов в двух разных фреймах данных / панд - PullRequest
0 голосов
/ 29 ноября 2018

Проблема: у меня 2 кадра данных;

  1. У df1 есть coil_id, sample_factor, seq.Каждый идентификатор coil_id имеет 449 записей (диапазон 1–499) и имеет около 1000 уникальных идентификаторов coil_id.
  2. df2 имеет идентификатор coil_id, sample, gauge.Каждый идентификатор coil_id имеет приблизительно 500 записей (диапазон 10-5000; может быть меньше) и имеет те же 1000 уникальных идентификаторов coil_id, что и в df1.

df1:

+-------+-----------------
|coil_id|sample_factor|SEQ
+-------+-----------------
|E101634|10.4066      |  1
|E101634|20.8132      |  2
|E101634|31.2198      |  3 
|E101634|41.6264      |  4
|E101634|5220.033     |449

df2:

+-------+------+------+--
|coil_id|SAMPLE|GAUGE |
+-------+------+------+--
|E101634|    10|0.0565|
|E101634|    20|0.0569|
|E101634|    30|0.0567|
|E101634|    40|0.0561|
|E101634|  5000| 0.055|

Я не могу объединить обе таблицы из-за разного количества записей.Если я сделаю это, мои значения образца и изменения датчика.Поэтому я не должен присоединяться.Затем мне нужно проверить, находится ли df1.sample_factor между df2.sample и df2.sample + 1 , а затем выполнить расчет по манометру.Пример: (если 10,4 лежат между 10 и 20, то 0,0565 + (((0,0569-0,0565 / 10) * (10,4-10)) ) в основном Pro-rate датчика.

Я хочу перебрать каждую строку из Sample_factor в df1 и проверить, находится ли она между sample [i] и sample [i + 1] в df2.а затем выполнить pro-rate на манометре и добавить результаты в df1.

Я пробовал это:

def new_gauge : for row in df1('sample_factor'):
    if df1['sample_factor'] > df2['sample'] and df1['sample_factor'] < df2['sample'] + 1:
        return df2['gauge']+(((df2['gauge']+1)-df2['gauge'])/10)*(df1['sample_factor']-df2['sample']))
df1['new_gauge'] = df1.apply(new_gauge)

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

Любая помощь приветствуется.Спасибо:)

ВЫХОД:

enter image description here

1 Ответ

0 голосов
/ 29 ноября 2018

Вот исходный пример данных, соответствующих ожидаемому результату

df1

   coil_id  sample_factor  SEQ
0  E101634        10.4066    1
1  E101634        20.8132    2
2  E101634        31.2198    3
3  E101634        41.6264    4
4  E101634        52.0330    5
5  E101634        62.4396    6
6  E101634      5220.0330  449

df2

   coil_id  SAMPLE   GAUGE
0  E101634      10  0.0550
1  E101634      20  0.0568
2  E101634      30  0.0543
3  E101634      40  0.0531
4  E101634      50  0.0529
5  E101634      60  0.0519

Первый шагmerge_asof, чтобы приблизить фактор выборки к выборке, которая является ближайшей.Затем вычислите столбец new_gauge для каждой строки.Однако мы на самом деле присвоим значение только в том случае, если sample_factor находится между значением его текущей строки и следующей строки, И coil_id одинаков для нее и следующей строки.

import pandas as pd

merged = pd.merge_asof(df2.assign(SAMPLE = df2.SAMPLE.astype('float')).sort_values('SAMPLE'), 
                       df1.sort_values('sample_factor'),
                       by='coil_id',
                       left_on='SAMPLE',
                       right_on='sample_factor',
                       direction='forward')
print(merged)
#   coil_id  SAMPLE   GAUGE  sample_factor  SEQ
#0  E101634    10.0  0.0550        10.4066    1
#1  E101634    20.0  0.0568        20.8132    2
#2  E101634    30.0  0.0543        31.2198    3
#3  E101634    40.0  0.0531        41.6264    4
#4  E101634    50.0  0.0529        52.0330    5
#5  E101634    60.0  0.0519        62.4396    6

# Now perform your calculation:
new_gauge = (merged.GAUGE.shift(1) 
             + ((merged.GAUGE - merged.GAUGE.shift(1))/10 
                 * (merged.sample_factor - merged.SAMPLE.shift(1))))

# Assign it only where it makes sense
# Assumes df2 was sorted on ['coil_id',  'SAMPLE']
mask = (merged.sample_factor.between(merged.SAMPLE, merged.SAMPLE.shift(-1)) 
        & (merged.coil_id == merged.coil_id.shift(-1)))

merged.loc[mask, 'new_gauge'] = new_gauge[mask] 

Вывод: merged

   coil_id  SAMPLE   GAUGE  sample_factor  SEQ  new_gauge
0  E101634    10.0  0.0550        10.4066    1        NaN
1  E101634    20.0  0.0568        20.8132    2   0.056946
2  E101634    30.0  0.0543        31.2198    3   0.053995
3  E101634    40.0  0.0531        41.6264    4   0.052905
4  E101634    50.0  0.0529        52.0330    5   0.052859
5  E101634    60.0  0.0519        62.4396    6        NaN

В этом случае мы не назначали последнюю строку, потому что в предоставленном вами подмножестве не было образца> 60.

...