Возврат всех 'значений условий if' в отдельном столбце - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть фрейм данных, к которому я применяю условие «если» для возврата определенных значений.Я хочу создать новый столбец, который будет иметь эти значения, но в случаях, когда удовлетворены несколько условий, я хочу, чтобы все 'возвращаемые' значения в этом столбце

Для следующего кадра данных, например

sample = pd.DataFrame({'Status':('reliable','non-reliable','reliable','non-reliable','reliable','reliable','non-reliable'),
                       'Gender': ('M','M','F','M','F','M','F'),
                       'Domain': ('Yes','No','Yes','No','Yes','No','Yes'),
                       'Paid': ('Paid','Paid','Paid','Not Paid','Paid','Not Paid','Paid')
        })

Условия выборки следующие.Например, если «Статус достоверен, а Пол - F», новый столбец должен иметь оба возвращаемых значения: «Надежное истина» и «F Истина»

def sample_column(row):
    if ((row['Status'] == 'reliable')):
        return 'reliable True'
    if ((row['Gender'] == 'F')):
        return 'F True'
    if ((row['Domain'] == 'Yes')):
        return 'Doamin True'

Наконец, построение столбца

sample = sample.assign(True_cases = sample.apply(sample_column,axis=1))

Я нашел здесь один пример решения (но я не могу его воспроизвести): Проверьте каждое условие в Python, если даже, если оно имеет значение true

Любая помощь в этом отношении будетс благодарностью.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Самым простым способом было бы сгенерировать маску, а затем объединить результат с выбором строки за строкой:

conds = {
    'Status': 'reliable',
    'Gender': 'M',
    'Domain': 'Yes',
    'Paid': 'Paid'
}
mask = pd.DataFrame().reindex_like(sample)
for c in mask.columns:
    mask[c] = sample[c] == conds[c]

sample['True Column'] = [
    ' '.join([
            '{} True'.format(s) for s in  sample.loc[i, mask.loc[i]]
    ]) for i in sample.index
]

Я использовал здесь довольно неуклюжий цикл double-for, но вы можете обернуть строкуформатирование в функции, чтобы получить лучшую производительность.Результаты будут:

  Domain Gender      Paid        Status  \
0    Yes      M      Paid      reliable   
1     No      M      Paid  non-reliable   
2    Yes      F      Paid      reliable   
3     No      M  Not Paid  non-reliable   
4    Yes      F      Paid      reliable   
5     No      M  Not Paid      reliable   
6    Yes      F      Paid  non-reliable   

                               True Column  
0  Yes True M True Paid True reliable True  
1                         M True Paid True  
2         Yes True Paid True reliable True  
3                                   M True  
4         Yes True Paid True reliable True  
5                     M True reliable True  
6                       Yes True Paid True  

РЕДАКТИРОВАТЬ

Я не уверен, какова будет цель для этого, но не похоже, что Панды будутлучший инструмент для этого вывода?ИМХО, если вы ищете длинные читаемые человеком строки, вы не должны пытаться поместить их в DataFrame.

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

conds = {
    'Status': ('reliable', lambda s: 'The status is {}'.format(s)),
    'Gender': ('M', lambda s: 'The gender is {}'.format(s)),
    'Domain': ('Yes', lambda s: 'Hello'),
    'Paid': ('Paid', lambda s: 'The bill has been settled')
}
mask = pd.DataFrame().reindex_like(sample)
for c in mask.columns:
    mask[c] = sample[c] == conds[c][0]

sample['True Column'] = [
    ' '.join([
            conds[c][1](s) for c, s in sample.loc[i, mask.loc[i]].iteritems()
    ]) for i in sample.index
]

В противном случае вы можете использовать свою функцию, нопросто добавьте каждый соответствующий оператор в список и присоедините его в конце:

def sample_column(row):
    ol = []
    if ((row['Status'] == 'reliable')):
        ol.append('reliable True')
    if ((row['Gender'] == 'F')):
        ol.append('F True')
    if ((row['Domain'] == 'Yes')):
        ol.append('Domain True')

    return ' '.join(ol)
sample['True Column'] = sample.apply(sample_column,axis=1)
0 голосов
/ 17 декабря 2018

Вы можете использовать функцию numpy where и &, чтобы связать ваши условия
См. np.where в приведенном ниже коде:

import pandas as pd
sample = pd.DataFrame({'Status':('reliable','non-reliable','reliable','non-reliable','reliable','reliable','non-reliable'),
                       'Gender': ('M','M','F','M','F','M','F'),
                       'Domain': ('Yes','No','Yes','No','Yes','No','Yes'),
                       'Paid': ('Paid','Paid','Paid','Not Paid','Paid','Not Paid','Paid')
        })

import numpy as np
sample['True_Column'] = np.where( 
        (sample['Status']=='reliable') & 
        (sample['Gender']=='F') & 
        (sample['Domain']=='Yes'), 
        'True', 'False')

print (sample)
#         Status Gender Domain      Paid True_Column
#0      reliable      M    Yes      Paid       False
#1  non-reliable      M     No      Paid       False
#2      reliable      F    Yes      Paid        True
#3  non-reliable      M     No  Not Paid       False
#4      reliable      F    Yes      Paid        True
#5      reliable      M     No  Not Paid       False
#6  non-reliable      F    Yes      Paid       False

Для более сложных условий вы можете использовать np.select.
Я не совсем уверен, как именно выполняется ваша логика для определения F True, reliable True и Domain True, поэтому вы должны быть более конкретны в своей логике.

...