pandas .применение анонимной функции, неожиданно возвращающей серию функциональных объектов - PullRequest
0 голосов
/ 07 апреля 2020

При чтении применяемой документации я попытался выполнить операцию, аналогичную той, которая продемонстрирована в этом примере (извлечено непосредственно из ссылки):

>>> df = pd.DataFrame([[4, 9]] * 3, columns=['A', 'B'])

>>> df

   A  B
0  4  9
1  4  9
2  4  9 

>>> df.apply(np.sum, axis=0)

A    12
B    27
dtype: int64

, где выбор оси = 0 указывает, что функция применяется к каждому столбцу, как мы можем видеть из новых индексов строк, являющихся именами предыдущих столбцов.

Но когда я применил (что я думал, было), произошло нечто неожиданное анонимная версия функции, а не ее прямое применение (отказ от ответственности: я знаю, что здесь нет причин использовать анонимную функцию. Я просто экспериментирую с тем, что делает для создания моей интуиции).

Вот моя функция:

>>> def my_function(a_column):
        values_in_col = list(set(a_column))
        new_strings_list = ["{}.{}".format(a_column.name,values) for values in values_in_col]
        return new_strings_list

и она работает так, как я ожидал:

>>> df

  A B
0 3 4
1 2 4
2 1 9

>>> df.apply(my_function, axis=0)

A ['A.1', 'A.2', 'A.3']
B ["B.4", "B.9"]

Но если я попытаюсь применить ее через лямбду, я получу серию функциональных объектов:

>>> df2 = df.apply(lambda x: my_function, axis=0)
>>> df2

A    <function generate_new_col_names at 0x11938ab90>
B    <function generate_new_col_names at 0x11938ab90>
dtype: object

>>> df2[0](df["A"])
['A.1', 'A.2', 'A.3']

>>> type(df2)
<class 'pandas.core.series.Series'>

>>> type(df2[1])
<class 'function'>

Итак, пара вещей.

1) Что случилось с "dtype: object", когда тип df2 [#] не является объектом? Я подумал, что dtype должен быть из pandas, а тип просто из python, и это объясняет это , но преобразование, похоже, не содержит .

2) Каждый «x», передаваемый в лямбду по очереди, должен быть столбцом из-за моего параметра axis = 0, верно? Так почему же я получаю что-то отличное от того, что получаю, когда подключаю каждый столбец напрямую?

>>> my_function(df.A)
['A.1', 'A.2', 'A.3']

>>> (lambda x: my_function(x))(df.A)
['A.1', 'A.2', 'A.3']

Кажется, что он выплевывает действительные функции вместо оцененных функций - так, куда идет ввод, тогда ? Я попробовал этот эксперимент, и он, похоже, оценивал функцию, а не возвращал функциональный объект:

>>> def my_other_func(x): # I'm just doing an external def'n to mirror what happened before
     return x + 1

>>> my_other_func(4)
5

>>> (lambda x: my_other_func(x))(4)
5

>>> test = (lambda x: my_other_func(x))(4)
>>> type(test)
int

Так что, похоже, использование «apply» связано с моим неправильным ожиданием предыдущего результата.

1 Ответ

0 голосов
/ 08 апреля 2020

Неважно, я понял это.

>>> df.apply(lambda x: my_function, axis=0)

дает ряд функциональных объектов, но

>>> df.apply(lambda x: my_function(x), axis=0)

дает желаемый результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...