Как сравнить несколько столбцов, содержащих значение списка, в Панд Python?

#python-3.x #pandas #list

Вопрос:

У меня есть следующие примеры данных

 ID          VAR1                            VAR2                                VAR3                                DATE
1           NaN                             [Timestamp('2012-08-03'), 'M']      [Timestamp('2012-08-03'), 'M']      2012-08-03
2           [Timestamp('2009-04-01'), 'F']  NaN                                 [Timestamp('2009-04-03'), 'F']      2009-04-01
3           NaN                             [Timestamp('2004-01-01'), 'M']      NaN                                 2004-01-01
4           NaN                             [Timestamp('2004-02-15'), 'M']      [Timestamp('2000-08-07'), 'M']      2000-08-07
 

Для каждой строки я хочу просмотреть VAR1 , VAR2 , и VAR3 и сравнить каждую с DATE другой . Каждый из трех столбцов будет иметь либо np.nan (отсутствующее значение), либо значение списка (содержащее дату и пол). Я хочу сравнить первый элемент списка со DATE столбцом. Если дата первого элемента отличается от значения более чем на день DATE , я хочу заменить это значение ячейки как np.nan .

Мне нравится использовать apply функцию Панд, так как мне ясна лежащая в ее основе логика.

Желаемая обработка df должна быть следующей:

 ID          VAR1                            VAR2                                VAR3                                DATE
1           NaN                             [Timestamp('2012-08-03'), 'M']      [Timestamp('2012-08-03'), 'M']      2012-08-03
2           [Timestamp('2009-04-01'), 'F']  NaN                                 NaN                                 2009-04-01
3           NaN                             [Timestamp('2004-01-01'), 'M']      NaN                                 2004-01-01
4           NaN                             NaN                                 [Timestamp('2000-08-07'), 'M']      2000-08-07
 

Это мой рабочий код

 df = df.apply(remove_value_if_unmatched_against_index_date, axis=1)

def remove_value_if_unmatched_against_index_date(df):
    vars = ['VAR1', 'VAR2', 'VAR3']
    for var in vars:
        if isinstance(df[var], list):   # doesn't work
        # if df[var].notnull():         # doesn't work
        # if df[var] != np.nan:         # doesn't work
            if abs(df[var][0] - df['DATE']) >= timedelta(days=1):
                df[var] = np.nan
    return df
 

Проблема в том, что ни одно из следующих действий ( if isinstance(df[var], list): , if df[var].notnull(): , и if df[var] != np.nan: ) не помогает проверить, есть ли в ячейке значение списка.

Ответ №1:

Попробуйте с bfill

 df['new'] = df.bfill(axis=1)['VAR1'].str[0]
 

Комментарии:

1. Спасибо, но по какой-то причине не сработало. Однако ваш ответ дал мне некоторую зацепку, и я обнаружил, что эта линия работает df['NEW'] = self.df.VAR1.apply(lambda x: x[1:-1].split(',')[0]) .