Pandas dataframe зацикливает все значения для определенного столбца

Работая с фреймворком данных pandas, предположим, что у меня есть фрейм данных с аналогичной структурой:

import pandas as pd
a_choise = ["True", "False", "False", "False", "True", "False", "False", "True", "True"]
b_choise = ["True", "True", "False", "False", "False", "False", "True", "True", "True"]
c_choise = ["False", "False", "True", "False", "True", "True", "False", "True", "False"]
a_n = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"]
b_n = ["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9"]
c_n = ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9"]
df = pd.DataFrame(
    {"a": list(range(1, 10)), "b": list(range(11, 20)), "c": range(21, 30), 
     "a_Cho":a_choise, "b_Cho":b_choise, "c_Cho":c_choise,
     "a_n":a_n, "b_n":b_n, "c_n":c_n}
)
    a   b   c   a_Cho   b_Cho   c_Cho   a_n b_n c_n
0   1   11  21  True    True    False   a1  b1  c1
1   2   12  22  False   True    False   a2  b2  c2
2   3   13  23  False   False   True    a3  b3  c3
3   4   14  24  False   False   False   a4  b4  c4
4   5   15  25  True    False   True    a5  b5  c5
5   6   16  26  False   False   True    a6  b6  c6
6   7   17  27  False   True    False   a7  b7  c7
7   8   18  28  True    True    True    a8  b8  c8
8   9   19  29  True    True    False   a9  b9  c9

Мне нужны новые 2 столбца (Выбор, Значение), которые соответствуют следующим условиям для всех значений в a_Cho, b_Cho и c_Cho

  • если a_Cho = true, то выберите = a_n, значение = a для соответствующего значения a_Cho elif a_Cho = false, затем перейдите к следующему
  • если b_Cho = true, то выберите = b_n, значение = b для соответствующего значения b_Choelif b_Cho = false, затем перейдите к следующему
  • если c_Cho = true, то выберите = c_n, значение = c для соответствующего значения c_Choelif c_Cho = false, затем перейдите к следующему
  • если x_Cho = false, то значение и выбор = Invalide

person Abdelsabour    schedule 01.04.2021    source источник
comment
df_val = [] df_name = [] cols = [coln_present, colm_present, .... ] для x в df[cols]: if df1['coln_present'][df1['coln_present'] ==True]: df_val.append (df1.coln_val) df_name.append(df1.p1_coln_name) elif df1['colm_present'][df1['colm_present'] ==True]: df_val.append(df1.colm_val) df_name.append(df1.p1_colm_name) еще: df_val.append(Not_Valid) df_name.append(Not_Valid) ##   -  person Abdelsabour    schedule 01.04.2021
comment
Есть пример кода, который я добавляю в сообщение   -  person Abdelsabour    schedule 01.04.2021


Ответы (1)


Отредактировано

Спасибо за обновление вашего вопроса. Я полагаю, что после вашего редактирования .loc быть полезным для вас. .loc позволяет нам выполнять логическое индексирование, захватывая строки на основе равенства столбцов.

Например, следующее получает все строки, где столбец a_Cho равен "True",

>>> df.loc[df.a_Cho.eq('True'), ['a_n', 'a']]
    a   b   c   a_Cho   b_Cho   c_Cho   a_n b_n c_n
0   1   11  21  True    True    False   a1  b1  c1
4   5   15  25  True    False   True    a5  b5  c5
7   8   18  28  True    True    True    a8  b8  c8
8   9   19  29  True    True    False   a9  b9  c9

Мы также можем выбрать подмножество столбцов, используя .loc.

>>> df.loc[df.a_Cho.eq("True"), ["a_n", "a"]].rename(columns={"a_n": "choise", "a": "value"})

где я использовал .rename() чтобы переименовать столбцы.

Используя описанный выше подход, мы можем выполнить логическое индексирование для каждого из указанных вами условий, а затем объединить результаты.

def new_col_names(x):
    return {x + "_n": "choise", x: "value"}

# logical criteria
only_a = df.a_Cho.eq("True")
only_b = df.a_Cho.eq("False") & df.b_Cho.eq("True")
only_c = df.a_Cho.eq("False") & df.b_Cho.eq("False") & df.c_Cho.eq("True")
invalid = df.a_Cho.eq("False") & df.b_Cho.eq("False") & df.c_Cho.eq("False")

df_a = df.loc[only_a, ["a_n", "a"]].rename(columns=new_col_names("a"))
df_b = df.loc[only_b, ["b_n", "b"]].rename(columns=new_col_names("b"))
df_c = df.loc[only_c, ["c_n", "c"]].rename(columns=new_col_names("c"))
df_inv = df.loc[invalid].assign(choise="invalide", value="invalide").copy()
df_inv = df_inv[["choise", "value"]]

df_new = pd.concat([df_a, df_b, df_c, df_inv])

Окончательный DataFrame выглядит так:

    choise    value
0   a1         1
4   a5         5
7   a8         8
8   a9         9
1   b2        12
6   b7        17
2   c3        23
5   c6        26
3   invalide  invalide

Обратите внимание, что значения индекса в левой части показывают исходные номера строк каждой записи. Если вам не нужны эти числа, вы можете передать параметр ignore_index=True в .concat.

Это ближе к тому, что вы хотели?

Оригинал

Привет и добро пожаловать в StackOverflow! Я не уверен, что полностью понимаю ваш вопрос. Например, в вашем примере кода не видно, что вы используете переменную цикла x на каждой итерации. Вам может помочь пример DataFrame, который имеет ту же структуру, что и тот, с которым вы работаете.

У меня сложилось впечатление, что ваш вопрос может быть похож на этот вопрос, в котором используется pd.melt.

Ваш DataFrame структурирован следующим образом?

>>> import pandas as pd
>>> df = pd.DataFrame(
    {"A": list(range(1, 10)), "B": list(range(11, 20)), "C": range(21, 30)}
)
>>> df.head()

    A   B   C
0   1   11  21
1   2   12  22
2   3   13  23
3   4   14  24
4   5   15  25
5   6   16  26
6   7   17  27
7   8   18  28
8   9   19  29

Если это так, вы можете использовать pd.melt, чтобы реструктурировать его, чтобы иметь два столбца, столбец имен столбцов и столбец значений столбцов, как вы описываете в своем вопросе.

Команда и вывод для примера DataFrame выше будут такими:

>>> pd.melt(df, value_vars=['A', 'B', 'C'])

  variable  value
0   A   1
1   A   2
2   A   3
3   A   4
4   A   5
5   A   6
6   A   7
7   A   8
8   A   9
9   B   11
10  B   12
11  B   13
12  B   14
13  B   15
14  B   16
15  B   17
16  B   18
17  B   19
18  C   21
19  C   22
20  C   23
21  C   24
22  C   25
23  C   26
24  C   27
25  C   28
26  C   29

Это похоже на то, что вы спрашиваете? Если нет, не могли бы вы привести пример DataFrame, с которым вы работаете, и пример того, как должен выглядеть конечный результат? Это может быть упрощенный или фиктивный пример.

person Alex Kluber    schedule 01.04.2021
comment
Спасибо Alex Kluber за ваш ответ, данные почти такие же, как и выше, с логическими столбцами A_bol, B_bol, C_bol, мне нужен столбец, который проверяет, если A_bol = true, затем возвращает значение A, если false, проверяет B_bol и так далее. - person Abdelsabour; 01.04.2021
comment
Я обновил свой ответ @Abdelsabour. Это отвечает на ваш вопрос? - person Alex Kluber; 02.04.2021