Подтвердить что ты не робот

Python Pandas: как добавить полностью новый столбец в фрейм данных внутри операции groupby/transform

Я хочу отметить некоторые кванты в моих данных, и для каждой строки DataFrame мне нужна запись в новом столбце, например, например. "xtile", чтобы сохранить это значение.

Например, предположим, что я создаю такой кадр данных:

import pandas, numpy as np
dfrm = pandas.DataFrame({'A':np.random.rand(100), 
                         'B':(50+np.random.randn(100)), 
                         'C':np.random.randint(low=0, high=3, size=(100,))})

И позвольте сказать, что я пишу свою собственную функцию для вычисления квинтиля каждого элемента в массиве. У меня есть своя функция для этого, но, например, просто обратитесь к scipy.stats.mstats.mquantile.

import scipy.stats as st
def mark_quintiles(x, breakpoints):
    # Assume this is filled in, using st.mstats.mquantiles.
    # This returns an array the same shape as x, with an integer for which
    # breakpoint-bucket that entry of x falls into.

Теперь реальный вопрос заключается в том, как использовать transform для добавления нового столбца в данные. Что-то вроде этого:

def transformXtiles(dataFrame, inputColumnName, newColumnName, breaks):
    dataFrame[newColumnName] = mark_quintiles(dataFrame[inputColumnName].values, 
                                              breaks)
    return dataFrame

И затем:

dfrm.groupby("C").transform(lambda x: transformXtiles(x, "A", "A_xtile", [0.2, 0.4, 0.6, 0.8, 1.0]))

Проблема в том, что приведенный выше код не добавит новый столбец "A_xtile". Он просто возвращает мой кадр данных без изменений. Если я сначала добавлю столбец, заполненный фиктивными значениями, например NaN, называемый "A_xtile", то он успешно переписывает этот столбец, чтобы включить правильные маркировки квинтиля.

Но крайне неудобно сначала писать в столбце для чего-то подобного, что я могу добавить на лету.

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

4b9b3361

Ответ 1

С какими проблемами вы сталкиваетесь с apply? Он работает для этого примера с игрушкой, а длина группы отличается:

In [82]: df
Out[82]: 
   X         Y
0  0 -0.631214
1  0  0.783142
2  0  0.526045
3  1 -1.750058
4  1  1.163868
5  1  1.625538
6  1  0.076105
7  2  0.183492
8  2  0.541400
9  2 -0.672809

In [83]: def func(x):
   ....:     x['NewCol'] = np.nan
   ....:     return x
   ....: 

In [84]: df.groupby('X').apply(func)
Out[84]: 
   X         Y  NewCol
0  0 -0.631214     NaN
1  0  0.783142     NaN
2  0  0.526045     NaN
3  1 -1.750058     NaN
4  1  1.163868     NaN
5  1  1.625538     NaN
6  1  0.076105     NaN
7  2  0.183492     NaN
8  2  0.541400     NaN
9  2 -0.672809     NaN