Условно заполняемые элементы в объекте pandas groupby – векторное решение с использованием numpy? Является ли групповой подход неправильным?

Хорошо, данные и логика такие же, как в этом вопросе, который я задал несколько дней назад. Но я хочу, чтобы вы ответили на него определенным образом, о котором я не упомянул в первой – numpy vectorization . Кроме того, у меня есть еще один вопрос о доверии groupbyapply .

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


Dataframe и логика для заполнения элементов:

У меня есть этот фиктивный фреймворк a

 arrays = [['bar', 'bar','bar', 'baz', 'baz', 'foo', 'foo', 'foo', 'qux', 'qux'], ['one', 'one','two', 'one', 'two', 'one', 'two', 'two', 'one','two']] tuples = list(zip(*arrays)) index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) a = pd.DataFrame(np.random.random((10,)), index = index) a[1] = pd.date_range('2017-07-02', periods=10, freq='5min') a Out[24]: 0 1 first second bar one 0.821371 2017-07-02 00:00:00 one 0.312364 2017-07-02 00:05:00 two 0.104821 2017-07-02 00:10:00 baz one 0.839370 2017-07-02 00:15:00 two 0.307262 2017-07-02 00:20:00 foo one 0.719300 2017-07-02 00:25:00 two 0.371118 2017-07-02 00:30:00 two 0.765483 2017-07-02 00:35:00 qux one 0.794236 2017-07-02 00:40:00 two 0.571231 2017-07-02 00:45:00 

Я хочу условно заполнить нижний элемент 0 го столбца в каждой first second группе в соответствии с логикой, описанной в этой функции

 def myfunc(g): if( len(g) >= 2): # if each group's length is greater than or equal to 2, then: if ((g.loc[g.index[-1], 0] > 0.5)): # If the last element of the 0th column of the group > 0.5, then: time_gap = g.loc[g.index[-1], 1] - g.loc[g.index[-2], 1] # Find the time difference between the last two records in 1st column g.loc[g.index[-1], 0] = time_gap # and assign it to the last element in the 0th column of that group else: g.loc[g.index[-1], 0] = 'ELSE' # Assign ELSE to the last element of the 0th column of the group return g 

Я использовал groupbyapply чтобы получить ниже результирующий фрейм данных, что я и ожидал.

  a.reset_index().groupby(['first', 'second']).apply(myfunc) Out[23]: first second 0 1 0 bar one 0.821371 2017-07-02 00:00:00 1 bar one ELSE 2017-07-02 00:05:00 correct 2 bar two 0.104821 2017-07-02 00:10:00 3 baz one 0.83937 2017-07-02 00:15:00 4 baz two 0.307262 2017-07-02 00:20:00 5 foo one 0.7193 2017-07-02 00:25:00 6 foo two 0.371118 2017-07-02 00:30:00 7 foo two 0 days 00:05:00 2017-07-02 00:35:00 correct 8 qux one 0.794236 2017-07-02 00:40:00 9 qux two 0.571231 2017-07-02 00:45:00 

Это замораживает мой компьютер, когда применяется в реальном наборе данных!


Мои вопросы

  1. Есть ли способ добиться результата с помощью numpy и vectorization ? (Векторизация объекта groupby)
  2. В ответе @ piRSquared он предположил, что groupby apply следует избегать в таком случае, когда он создает отдельный блок данных для каждой группы. У меня ранее был какой-то другой недоумение плохой опыт, который трудно отлаживать при использовании groupby apply . При всем этом я теряю свою веру в groupbyapply , что, я думаю, является решением pandas чтобы избегать for loops на объектах groupby; он даже падает до полной итерации через набор данных, как показано в ответе @ piRSquared. Итак, groupbyapply подход «ничего хорошего» для таких задач?

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

Я не думаю, что это относится к «обзору кода», так как я не прошу пересмотреть код, скорее я хочу знать методы векторизации, применяемые к объектам groupby

Python - лучший язык программирования в мире.