Лучший способ заменить элементы в списке / фрейме данных - PullRequest
0 голосов
/ 14 сентября 2018

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

логика:

    if col("a") not empty & col("b") negative 
    => create col("ret_a") = 2*min(col("a")) - col("a")
    else col("ret_a") = col("a")

Код, который я использую и который выполняет работу (но не очень):

# a
df["ret_a"] = np.where(
    np.logical_and(pd.notnull(df["a"]), df["b"] < 0),
    2*df["a"].min()- df["a"],
    df["a"])

Проблема в том, что у меня есть куча условий ... и я не думаю, что такое условие, как "<0", может быть сохранено в dict {} для использования pd.map () </p>

Затем я попытался построить что-то, используя:

df['i'] = np.select(conditions, choices,)

с 'i' 'условиями' и 'вариантами выбора':

i= [
    'RETURN_COM_EQY_',                     # a
    'INTEREST_COVERAGE_RATIO_',            # b
    'TOT_DEBT_TO_TOT_CAP_',                # c
    'TOT_DEBT_TO_TOT_EQY_',                # d
    'NET_DEBT_TO_EBITDA_',                 # e
    'NET_INTEREST_COVERAGE_']              # f

conditions = [
    (df['TOTAL_EQUITY_'] < 0),            # a
    (df['IS_INT_EXPENSE_'] < 0),          # b
    (df['NET_DEBT_'] < 0),                # c
    (df['NET_DEBT_'] < 0),                # d
    (df['NET_DEBT_'] < 0),                # e1
    (df['EBIT_'] < 0),                    # e2
    (df['IS_INT_EXPENSE_'] < 0)]          # f

choices = [
    2*df["RETURN_COM_EQY_"].min() - df["RETURN_COM_EQY_"],                         # a
    2*df["INTEREST_COVERAGE_RATIO_"].min() - df["INTEREST_COVERAGE_RATIO_"],       # b
    2*df["TOT_DEBT_TO_TOT_CAP_"].max() - df["TOT_DEBT_TO_TOT_CAP_"],               # c
    2*df["TOT_DEBT_TO_TOT_EQY_"].max() - df["TOT_DEBT_TO_TOT_EQY_"],               # d
    2*df["NET_DEBT_TO_EBITDA_"].max() - df["NET_DEBT_TO_EBITDA_"],                 # e1
    2*df["NET_DEBT_TO_EBITDA_"].min() - df["NET_DEBT_TO_EBITDA_"],                 # e2
    2*df["NET_INTEREST_COVERAGE_"].min() - df["NET_INTEREST_COVERAGE_"],           # f
    ]

полный код для этой операции будет:

    # a
df["ret_mean_RETURN_COM_EQY_"] = np.where(
    np.logical_and(pd.notnull(df["mean_RETURN_COM_EQY_"]),
                   df["mean_TOTAL_EQUITY_"] < 0),
    2*df["mean_RETURN_COM_EQY_"].min() 
    - df["mean_RETURN_COM_EQY_"],
                   df["mean_RETURN_COM_EQY_"])

# b
df["ret_mean_INTEREST_COVERAGE_RATIO_"] = np.where(
    np.logical_and(pd.notnull(df["mean_INTEREST_COVERAGE_RATIO_"]),
                   df["mean_IS_INT_EXPENSE_"] < 0),
    2*df["mean_INTEREST_COVERAGE_RATIO_"].min() 
    - df["mean_INTEREST_COVERAGE_RATIO_"],
                   df["mean_INTEREST_COVERAGE_RATIO_"])
# c
df["ret_mean_TOT_DEBT_TO_TOT_CAP_"] = np.where(
    np.logical_and(pd.notnull(df["mean_TOT_DEBT_TO_TOT_CAP_"]),
                   df["mean_NET_DEBT_"] < 0),
    2*df["mean_TOT_DEBT_TO_TOT_CAP_"].max()
    - df["mean_TOT_DEBT_TO_TOT_CAP_"],
                   df["mean_TOT_DEBT_TO_TOT_CAP_"])

# d
df["ret_mean_TOT_DEBT_TO_TOT_EQY_"] = np.where(
    np.logical_and(pd.notnull(df["mean_TOT_DEBT_TO_TOT_EQY_"]),
                   df["mean_NET_DEBT_"] < 0),
    2*df["mean_TOT_DEBT_TO_TOT_EQY_"].max()
    - df["mean_TOT_DEBT_TO_TOT_EQY_"],
                   df["mean_TOT_DEBT_TO_TOT_EQY_"])

# e1
df["ret_mean_NET_DEBT_TO_EBITDA_"] = np.where(
    np.logical_and(pd.notnull(df["mean_NET_DEBT_TO_EBITDA_"]),
                   df["mean_NET_DEBT_"] < 0),
    2*df["mean_NET_DEBT_TO_EBITDA_"].max()
    - df["mean_NET_DEBT_TO_EBITDA_"],
                   df["mean_NET_DEBT_TO_EBITDA_"])

# e2
df["ret_mean_NET_DEBT_TO_EBITDA_"] = np.where(
    np.logical_and(pd.notnull(df["mean_NET_DEBT_TO_EBITDA_"]),
                   df["mean_EBIT_"] < 0),
    2*df["mean_NET_DEBT_TO_EBITDA_"].min()
    - df["mean_NET_DEBT_TO_EBITDA_"],
                   df["ret_mean_NET_DEBT_TO_EBITDA_"]) # different here

# f
df["ret_mean_NET_INTEREST_COVERAGE_"] = np.where(
    np.logical_and(pd.notnull(df["mean_NET_INTEREST_COVERAGE_"]),
                   df["mean_IS_INT_EXPENSE_"] < 0),
    2*df["mean_NET_INTEREST_COVERAGE_"].min()
    - df["mean_NET_INTEREST_COVERAGE_"],
                   df["mean_NET_INTEREST_COVERAGE_"])

1 Ответ

0 голосов
/ 15 сентября 2018

Эта функция должна выполнять работу:

def func(df, i_n, condition, choice):
   name = "ret_" + i_n
   df[name] = df[i_n]
   df.loc[(pd.notnull(df[i_n])) & (condition), name] = choice

for i_n, condition, choice in zip(i, conditions, choices):
   func(df, i_n, condition, choice)
...