Я создал функцию, которая проверяет три столбца и применяет условия, которые я упомянул в функции. Я установил первый столбец (col0) как None. Вот как выглядят мои столбцы:

rule_id  col0  col1 col2  
50378     2      0    0  
50402    12      9    6  
52879     0      4    3  

Здесь столбец «rule_id» является индексом

Это мой код:

for i, j, in dframe.groupby('tx_id'):

    df1 = pd.DataFrame(j)

    df = df1.pivot_table(index = 'rule_id' , columns = ['date'], values = 
      'rid_fc', aggfunc = np.sum,  fill_value = 0)

    coeff = df.T

# compute the coefficients
    for name, s in coeff.items():
        top = 100              # start at 100
        r = []
        for i, v in enumerate(s):
            if v == 0:         # reset to 100 on a 0 value
                top=100
            else:
                top = top/2    # else half the previous value
            r.append(top)
        coeff.loc[:, name] = r # set the whole column in one operation

# transpose back to have a companion dataframe for df
    coeff = coeff.T

    def build_comp(col1, col2, i, col0 = None):

        conditions = [(df[col1] == 0) & (df[col2] == 0)  ,(df[col1] == df[col2]) , (df[col1] != 0) & (df[col2] != 0) & (df[col1] > df[col2]) , 
                      (df[col1] != 0) & (df[col2] != 0) & (df[col1] < df[col2]) ,(df[col1] != 0) & (df[col2] == 0)]

        choices = [np.nan , coeff[col1] , df[col2]/df[col1]*coeff[col1],df[col2]/df[col1]* coeff[col1],100]

        condition = [(df[col2] != 0) , (df[col2] == 0)]


        choice = [100 , np.nan]

        if col0 is not None:
            conditions.insert(1, (df[col1] != 0) & (df[col2] == 0) & (df[col0] != 0))
            choices.insert(1, 25)

            condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
            choice.insert(0, 25)

        if col0 is None:
            condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
            choice.insert(0, 25)


        df['comp{}'.format(i)] = np.select(conditions , choices , default = np.nan)
        df['comp{}'.format(i+1)] = np.select(condition , choice)


    col_ref = None
    col_prev = df.columns[0]
    for i, col in enumerate(df.columns[1:], 1):
        build_comp(col_prev, col, i, col_ref)
        col_ref = col_prev
        col_prev = col

    if len(df.columns) == 1:
       df['comp1'] = [100] * len(df) 

'df' - это фрейм данных, в котором есть эти столбцы. Как вы можете видеть, в эту функцию вовлечено несколько условий. Я хочу добавить еще один, который как col0, так и col1 - None, но я не знаю как. Я попытался добавить условие внутри if col0 is None:, например:

if col1 is None:
     conditions.insert(0, (df[col2] != 0)
     choices.insert(0, 100)

Но это не работает. Предположим, у меня есть только один столбец (col2), а col0 и col1 отсутствуют, поэтому результат должен быть таким, как указано в моем условии:

rule_id  col2  comp1
50378     2     100
51183     3     100

Но столбец comp не создается. Если бы вы, ребята, могли бы помочь мне достичь этого, я был бы очень признателен.

Текущий код (Правка): после использования кода @ предложил Джоэл. Я сделал изменения. Это код:

def build_comp(col2, i, col0 = None, col1 = None): 

        conditions = [(df[col1] == df[col2]) & (df[col1] != 0) & (df[col2] != 0) , (df[col1] != 0) & (df[col2] != 0) & (df[col1] > df[col2]) , 
                      (df[col1] != 0) & (df[col2] != 0) & (df[col1] < df[col2]) ,(df[col1] != 0) & (df[col2] == 0)]

        choices = [50 , df[col2]/df[col1]*50,df[col2]/df[col1]* 25,100]

        condition = [(df[col2] != 0) , (df[col2] == 0)]
        choice = [100 , np.nan]

        if col0 is not None:
            conditions.insert(1, (df[col1] != 0) & (df[col2] == 0) & 
           (df[col0]!= 0))
            choices.insert(1, 25)

            condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
            choice.insert(0, 25)

        else:  
            condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
            choice.insert(0, 25)

        if col1 is None:
            conditions.insert(0, (df[col2] != 0))
            choices.insert(0, 100)
            conditions.insert(0, (df[col2] == 0))
            choices.insert(0, np.nan)



    df['comp{}'.format(i)] = np.select(conditions , choices , default = np.nan)
    df['comp{}'.format(i+1)] = np.select(condition , choice)


col_ref = None
col_prev = df.columns[0]
for i, col in enumerate(df.columns[1:], 1):
    build_comp(col,i, col_ref , col_prev)
    col_ref = col_prev
    col_prev = col  

Когда я запускаю этот код, я все еще не получаю столбец comp. Вот что я получаю:

rule_id  col2  
50378     2     
51183     3     

Но я должен получить это согласно моей логике:

 rule_id  col2  comp1
50378     2     100
51183     3     100

Я знаю, что с логикой for loop и col_prev что-то не так, но я не знаю, что именно.

Изменить: Для большего упрощения, вот как выглядит мой df:

enter image description here

Это мой `df 'выглядит после применения моего кода:

enter image description here

Но теперь предположим, что присутствует только один столбец отметки времени, например:

enter image description here

Тогда я хочу, чтобы результат был таким:

date    2018-12-11 13:41:51  comp1
rule_id                        
51183         1                100
52368         1                100
0
vesuvius 3 Июл 2019 в 15:20

3 ответа

Лучший ответ

Когда df имеет один столбец, цикл for пропускается (то есть код в цикле не выполняется).

Чтобы добавить столбец для случая, когда df имеет один столбец, добавьте следующий код в конец:

if len(df.columns) == 1:
    df['comp1'] = [100] * len(df)

Это предполагает, что rule_id это метки строк. Если нет, то сравните с 2 вместо 1.

1
user650654 11 Июл 2019 в 21:42

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

Следовательно, ваш код должен выглядеть примерно так:

def build_comp(col2, i, col0 = None, col1 = None):  # <== changing here

    if col1 is not None:  # we can compare <== EDITED HERE
        conditions = [(df[col1] == 0) & (df[col2] == 0),
                      (df[col1] == df[col2]),
                      (df[col1] != 0) & (df[col2] != 0) & (df[col1] > df[col2]),
                      (df[col1] != 0) & (df[col2] != 0) & (df[col1] < df[col2]),
                      (df[col1] != 0) & (df[col2] == 0)]

    choices = [np.nan,
               50,
               df[col2] / df[col1] * 50,
               df[col2] / df[col1] * 25,
               100]

    condition = [(df[col2] != 0),
                 (df[col2] == 0)]
    choice = [100,
              np.nan]

    if col0 is not None:
        conditions.insert(1, (df[col1] != 0) & (df[col2] == 0) & (df[col0] != 0))
        choices.insert(1, 50)

        condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
        choice.insert(0, 25)

    else:  # if col0 is None:  # <== use `else` instead of testing opposite
        condition.insert(0,(df[col2] != 0) & (df[col1] != 0))
        choice.insert(0, 25)

    df['comp{}'.format(i)] = np.select(conditions , choices , default = np.nan)
    df['comp{}'.format(i+1)] = np.select(condition , choice)

Осторожно, вы используете choices и choice для разных вещей, это вам не поможет.

1
Joël 11 Июл 2019 в 14:36

Почему вы используете None? ИМО лучше использовать NaN.

-1
wordinone 4 Июл 2019 в 14:31