Ошибка DataFrame.apply (): «<Series> не является допустимой функцией для объекта« Серия »» - PullRequest
0 голосов
/ 24 апреля 2020

Я получаю AttributeError от pandas .DataFrame.apply (). Несмотря на это, функция, кажется, работает, но я хотел бы лучше понять apply (), поэтому я все равно отправляю этот вопрос ...

У меня есть два кадра данных, например:

a = pd.DataFrame(data = {
    'ID': ['123', '456', '789'],
    'TIME': [1.5, 2, 3]
})

b = pd.DataFrame(data = {
    'ID': ['123', '456', '789'] * 2,
    'TIME_START': [1, 3, 3, 2, 1, 5],
    'TIME_END': [5, 4, 6, 6, 3, 6],
    'CORR_KEY': ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr']
})

Я объединяю их так:

c = a.merge(b, how = 'inner', on = 'ID')

И получаю следующее:

print(c)

    ID  TIME  TIME_START  TIME_END CORR_KEY
0  123   1.5           1         5      abc
1  123   1.5           2         6      jkl
2  456   2.0           3         4      def
3  456   2.0           1         3      mno
4  789   3.0           3         6      ghi
5  789   3.0           5         6      pqr

Теперь мне нужно удалить записи в c где TIME_START <= <strong>TIME <= <strong>TIME_END - ЛОЖЬ. Таким образом, я получаю только те записи, которые имеют CORR_KEY . (Например, CORR_KEY для ID 123 - это ab c, НЕ jkl.)

Я использую следующую функцию и применяю ее к кадру данных :

def drop_records(df):
    start_condition = df['TIME_START'] <= df['TIME']
    end_condition = df['TIME'] <= df['TIME_END']

    df.drop(df[~(start_condition) | ~(end_condition)].index, inplace = True)

    return df

c = c.apply(drop_records(c))

Результат:

AttributeError: 'ID' не является допустимой функцией для объекта 'Series'

HOWEVER, проверка c снова, я получаю ожидаемый вывод:

print(c)

    ID  TIME  TIME_START  TIME_END CORR_KEY
0  123   1.5           1         5      abc
3  456   2.0           1         3      mno
4  789   3.0           3         6      ghi

Итак, что вызывает AttributeError?

Спасибо!

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Вы перебиваете решение. Вы можете использовать query для непосредственного получения результата:

c = c.query('TIME_START <= TIME <= TIME_END')

print(c)
    ID  TIME  TIME_START  TIME_END CORR_KEY
0  123   1.5           1         5      abc
3  456   2.0           1         3      mno
4  789   3.0           3         6      ghi
0 голосов
/ 24 апреля 2020

Когда вы делаете apply, кадр данных делится на серии, по одному для каждого столбца, и функция применяется к ser ie. Поскольку ID - это только первый столбец, apply пытается выполнить drop_records(c), но отправляет им ser ie из ID, что приведет к AttributeError.

. neet для apply функции здесь, просто:

c = drop_records(c)

Или с использованием логических масок:

mask = (c.TIME_START <= c.TIME) & (c.TIME <= c.TIME_END)
c = c[mask]

Или даже запрос, как предложил @Sandeep Kadapa.

...