новый столбец на основе условий строк и столбцов pandas python - PullRequest
0 голосов
/ 19 мая 2018

У меня есть пример набора данных:

import pandas as pd
import numpy as np

d = {

 'ID': ['A','B','C','D','E'],
 'index_1':[2,0,2,-2,0],
 'index_2':[-2,-2,0,0,0],
 'index_3':[2,2,2,2,0],
 'index_4':[2,2,0,-2,0],
 'index_total':[2,2,2,2,2]
}
df = pd.DataFrame(d)

это выглядит так:

   ID   index_1  index_2  index_3   index_4   index_total
0   A        2       -2        2        2            2
1   B        0       -2        2        2            2
2   C        2        0        2        0            2
3   D       -2        0        2       -2            2
4   E        0        0        0        0            2

я хочу создать столбец с именем 'flag' на основе следующих условий длякаждая строка :

  1. , если какой-либо из столбцов 'index_1', 'index_2', 'index_3', 'index_4' содержит значение -2 AND 'index_total'= 2, тогда flag = 1
  2. , если столбцы 'index_1', 'index_2', 'index_3', 'index_4' содержат только значение 0 AND 'index_total' = 2, тогда flag = 1
  3. else: flag = 0

желаемый вывод:

    ID   index_1  index_2  index_3   index_4   index_total   flag
0    A        2       -2        2        2            2        1
1    B        0       -2        2        2            2        1
2    C        2        0        2        0            2        0
3    D       -2        0        2       -2            2        1
4    E        0        0        0        0            2        1

мои попытки (заметьте, я использую циклы для index_1, index_2, index_3 иИмена столбцов index_4 вместо того, чтобы записывать их, потому что в моем фактическом наборе данных есть более 70 столбцов index_)

1-я попытка:

for colname in df.columns:
    if "index_" in colname:
        df[colname] = df[colname].astype(int)  
 #making sure the numbers are all integer for comparison
    if ((df[colname] == -2).any() and df['index_total']==2):
         df['flag'] = 1
  #this doesn't work , it's going by columns not rows

2-я попытка:

 for index, row in df.iterrows():    
    for colname in df.columns:
       if "index_" in colname:
           if( (df[colname][index] == -2).any() and df['index_total']==2 ):
                df['flag'] = 1
 # i stopped writing the other conditions because this one doesn't work

Ответы [ 3 ]

0 голосов
/ 19 мая 2018

Напишите функцию, которая принимает строку и выполняет вашу логику:

Поскольку вы говорите, что у вас много столбцов, мы будем использовать any и all из библиотеки std.Предполагается, что index_total является последним столбцом, а ID является первым столбцом

def functo(row):
    if (any([i == -2 for i in row[1:-1]]) and row[-1] == 2):
        return 1
    elif (all(i == 0 for i in row[1:-1]) and row[-1] == 2):
        return 1
    else:
        return 0

и применяется к вашему фрейму данных:

df['flag'] = df.apply(functo, axis=1)

Мы используем axis=1 дляпримените вашу функцию к строкам вместо столбцов.

Кроме того, совет: я бы не стал называть столбцы index, потому что в терминологии панд индекс относится к строке.

0 голосов
/ 19 мая 2018

any, all и логическое маскирование

(комментарии вписаны.)

# sub-select your column of interest
i = df.filter(regex=r'index_\d+')
# this is a common mask, we'll compute it once and use later
j = df['index_total'].eq(2)

m1 = i.eq(-2).any(1) & j   # first condition
m2 = i.eq(0).all(1) & j    # second condition
# compute the union of the masks and convert to int
df['flag'] = (m1 | m2).astype(int)

df
  ID  index_1  index_2  index_3  index_4  index_total  flag
0  A        2       -2        2        2            2     1
1  B        0       -2        2        2            2     1
2  C        2        0        2        0            2     0
3  D       -2        0        2       -2            2     1
4  E        0        0        0        0            2     1
0 голосов
/ 19 мая 2018

Первое условие:

df[cols].eq(-2).any(1) & df['index_total'].eq(2)

# (array([0, 1, 3], dtype=int64),)

Второе условие:

df[cols].eq(0).all(1) & df['index_total'].eq(2)

# (array([4], dtype=int64),)

np.where для создания нового столбца:

c1 = df[cols].eq(-2).any(1) & df['index_total'].eq(2)
c2 = df[cols].eq(0).all(1) & df['index_total'].eq(2)

df['Flag'] = np.where(c1 | c2, 1, 0)

  ID  index_1  index_2  index_3  index_4  index_total       Flag
0  A        2       -2        2        2            2          1
1  B        0       -2        2        2            2          1
2  C        2        0        2        0            2          0
3  D       -2        0        2       -2            2          1
4  E        0        0        0        0            2          1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...