Обновления строк для Pandas DF на основе условий - PullRequest
0 голосов
/ 17 января 2019

У меня есть фрейм данных pandas со следующими столбцами (тип pk1, pk2, qty_6, qty_7). Я имею тип как предикат_90, переопределение_90, прогнозирование_50, переопределение 50. Теперь на основе комбинации pk1 и pk2. Если для типа предиката_50, предикат_90 содержит некоторое значение для переопределения_50, переопределить_90, кроме NaN, я хочу обновить столбцы данных в кадре предиката_50, предиката_90 с переопределением_50 и override_90 соответственно. Кроме того, я хочу зафиксировать это изменение в логическом столбце с именем qty_6_overridden, qty_7_overridden. Также я хочу зафиксировать разницу между ними в столбце qty_6_dev, qty_7_dev. qty_6_dev = qty_6 override - qty_6 предсказано.

Я пробовал решение перебрать все строки для DF, получить соответствующую строку и обновить. Ниже приведен мой код, который работает, но не очень хорошо читается и не может масштабироваться по большему числу строк.

import pandas as pd
import numpy as np
import math

data=[
['B01FV0FBX4','2019-01-13','predicted_90',2207.931,2217.841],
['B01FV0FBX4','2019-01-13','predicted_50',1561.033,1521.567],
['B01FV0FBX4','2019-01-13','override_90',1973.000,np.NaN],
['B01FV0FBX4','2019-01-13','override_50',1233.000,np.NaN],
['B01FV0FBX4','2019-01-06','override_50',np.NaN,1233.000],
['B01FV0FBX4','2019-01-06','predicted_50',1210.129,1213.803],
['B01FV0FBX4','2019-01-06','override_90',np.NaN,1973.000],
['B01FV0FBX4','2019-01-06','predicted_90',1911.205,1921.594]
]
df = pd.DataFrame(data,columns=['pk1','pk2', 'type', 'qty_6', 'qty_7'])

override_map = {
    "predicted_50" : "override_50",
    "predicted_90" : "override_90"
}

def transform_df(df):
    transformed_df = pd.DataFrame()
    for index, row in df.iterrows():
        row_type = row['type']
        row_pk1 = row['pk1']
        row_pk2 = row['pk2']

        if row_type in override_map.keys():
            override_type = override_map.get(row_type)
        else:
            for i in range(6,8):
                qty_dev_col = 'qty_'+str(i)+'_dev'
                qty_override_col = 'qty_'+str(i)+'_overridden'
                row[qty_dev_col] = 0
                row[qty_override_col] = False
            transformed_df=transformed_df.append(row, ignore_index=True)
            continue
        corr_df = df.loc[(df.type == override_type) 
                         & (df.pk1 == row_pk1) 
                         & (df.pk2 == row_pk2)]

        for i in range(6,8):
            qty_col = 'qty_'+str(i)
            qty_dev_col = 'qty_'+str(i)+'_dev'
            qty_override_col = 'qty_'+str(i)+'_overridden'
            if not (math.isnan(corr_df[qty_col])) and (corr_df[qty_col].values[0] != row[qty_col]):
                row[qty_dev_col] = corr_df[qty_col].values[0] - row[qty_col]
                row[qty_col] = corr_df[qty_col].values[0]
                row[qty_override_col] = True
            else:
                row[qty_dev_col] = 0
                row[qty_override_col] = False
        transformed_df=transformed_df.append(row, ignore_index=True)
    return transformed_df

x1 = transform_df(df)

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

data=[
['B01FV0FBX4','2019-01-13','predicted_90',1973.000,2217.841,-234.931,0,True,False],
['B01FV0FBX4','2019-01-13','predicted_50',1233.000,1521.567,-328.033,0,True,False],
['B01FV0FBX4','2019-01-13','override_90',1973.000,np.NaN,0,0,False,False],
['B01FV0FBX4','2019-01-13','override_50',1233.000,np.NaN,0,0,False,False],
['B01FV0FBX4','2019-01-06','override_50',np.NaN,1233.000,0,0,False,False],
['B01FV0FBX4','2019-01-06','predicted_50',1210.129,1213.000,0,19.197,False,True],
['B01FV0FBX4','2019-01-06','override_90',np.NaN,1973.000,0,0,False,False],
['B01FV0FBX4','2019-01-06','predicted_90',1911.205,1973.000,0,51.406,False,True]
]
df = pd.DataFrame(data,columns=['pk1','pk2', 'type', 'qty_6', 'qty_7','qty_6_dev','qty_7_dev', 'qty_6_overridden','qty_7_overridden'])

Логика работает, как и ожидалось, но я не думаю, что это лучший способ для достижения этой цели, так как если я попытаюсь запустить это по большему DF, как с 10,0000 строк. Это работает долго. Может кто-нибудь сказать мне лучшее решение?

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