установить два столбца с одинаковыми условиями - PullRequest
0 голосов
/ 16 января 2020

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

np.random.seed(seed=1)
df=pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('abcd'))

#condition 1
df["accepted"]=np.where(df.a<10, "No", "")
df["reason"]=np.where(df.a<10, "a less than 10 ", "")

#condition 2
df["accepted"]=np.where(df.b<30, "No", df.accepted)
df["reason"]=np.where(df.b<30, df.reason+"b less than 10 ", df.reason)

набор условий велик, и они в некотором роде сложны в реальном сценарии. Условия со временем будут меняться, и я хочу уменьшить объем обслуживания, поэтому я попытался объединить два оператора where в одно:

df[["accepted","reason"]]=np.where(df.c>20, ["No",df.reason + "c higher than 20 "], [df.accepted,df.reason])

, но получил:

ValueError : операнды не могут быть переданы вместе с фигурами (100,) (2,) (2,100)

Есть ли способ установить два столбца в одном выражении where ? Или у вас есть альтернативный подход, чтобы предложить? Моя цель - поддерживать последовательный подход (т. Е. Отклонять условие строк по условию) и иметь способ оценить, какое условие отклонило запись. Мой фрейм данных содержит около 100 тыс. Записей.

Ответы [ 2 ]

2 голосов
/ 16 января 2020

Вы можете использовать apply метод. См. Реализацию ниже:

def update(row):
    if row.c > 20:
        row.accepted = "No"
        row.reason = row.reason + 'c higher than 20 '
    return row

df = df.apply(lambda row: update(row), axis=1)

Вы можете написать все свои условия в методе update().

1 голос
/ 17 января 2020

Мое предложение: используйте np.select. Создайте свой список условий в правильном порядке, затем создайте список ожидаемых результатов, снова в правильном порядке и передайте его в np.select. https://docs.scipy.org/doc/numpy/reference/generated/numpy.select.html

Надеюсь, что приведенный ниже код поможет:

np.random.seed(seed=1)
df=pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('abcd'))

cond1 = df['a']<10
cond2 = df['b']<30
cond3 = (df['a']<10) & (df['b']<30)
cond4 = ~((df['a']<10) | (df['b']<30))
condlist=[cond3,cond2,cond1,cond4]
choicelist = ['both','no','no','']
reasonlist = [ 'a less than 10, b less than 10','a less than 10','b less than 
                                                                  10','']

df['accept']=np.select(condlist,choicelist)
df['reason'] = np.select(condlist,reasonlist)

df.head(

    a   b   c   d   accept  reason
0   37  12  72  9   no      a less than 10
1   75  5   79  64  no      a less than 10
2   16  1   76  71  no      a less than 10
3   6   25  50  20  both    a less than 10, b less than 10
4   18  84  11  28      

При этом вы можете добавлять дополнительные условия или изменять условия с течением времени.

Обратите внимание, что сначала я ставлю условие «меньше 10, b меньше 10» перед остальными. Вся цель состоит в том, чтобы при перечислении условий был установлен правильный порядок.

...