Обновление pandas dataframe внутри функции, вызываемой через DataFrame.groupby.apply - PullRequest
0 голосов
/ 24 сентября 2018

Это кажется очень фундаментальным вопросом, который был бы задан ранее, но я не могу найти ответ.

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

import pandas as pd
df = pd.DataFrame(list(zip(list('abababa'), [1,2,3,4,1,2,3], [5,4,3,2,1,2,3])), 
                  columns=["ab", "x", "y"])
print(df,"\n")

### Attempt #1
def change_y(tab):
    tab.y = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #2
def change_y(tab):
    tab.loc[:,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #3
def change_y(tab):
    tab.at[:,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #4
def change_y(tab):
    tab.loc[tab.index,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

Однако это работает:

### Attempt #5 -- This one works
def change_y(big_tab,tab):
    big_tab.loc[tab.index,"y"] = tab.y.min()

df.groupby(df.ab).apply(lambda tab: change_y(df,tab))
print(df,"\n")

Итак, я понимаю, почему работает # 5, но я не понимаю, почему ни один из 1-4работает.Я неправильно понял, групповой?Я подумал, что он не сделал копию базового фрейма данных, а просто сконструировал индексы на базовом фрейме данных и передал их функции.В этом случае, по крайней мере, один из 1-4 должен работать!

Действительно ли groupby создает копию кадра данных для каждой группы?Кажется, что это было бы излишним и неэффективным.

Если оно делает копию, есть ли другое решение, кроме # 5?Я понимаю, что я мог бы просто сделать функцию создания новой Серии и назначить ее в конце:

df.y = df.groupby(df.ab).apply(lambda tab: tab.x = tab.y)

, но по другим причинам, это не то, что я хочу сделать в этом случае.

1 Ответ

0 голосов
/ 25 сентября 2018

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

Спасибо всем, кто помог.

import pandas as pd
df = pd.DataFrame(list(zip(list('abababa'), [1,2,3,4,1,2,3], [5,4,3,2,1,2,3])), 
                  columns=["ab", "x", "y"])
print(df,"\n")

def change_y(big_tab,ab_tab):
    indx = ab_tab.index
    tab = big_tab.loc[indx]  # I can do all but the update with tab.
    big_tab.loc[indx,"y"] = tab.y.min()

df.ab.groupby(df.ab).apply(lambda ab_tab: change_y(df,ab_tab))
print(df,"\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...