Панды, применить пользовательскую функцию к данным, сгруппированным по строковым индексам - PullRequest
1 голос
/ 08 мая 2019

У меня есть данные, которые я хочу сгруппировать по городам и дням (отдельные столбцы) и рассчитать новое значение, используя оставшиеся столбцы. В частности, в других столбцах указано количество людей по расе за 6 гонок. Поэтому у меня 8 столбцов, два сгруппированных и 6, которые я хочу обобщить. Я хочу обобщить их, рассчитав энтропию за день города.

Однако город и день - это строки, и моя функция энтропии не нравится. Работает, когда столбцы группировки int64. Я попытался преобразовать столбцы города и дня в фиктивные переменные, но ошибка остается.

Заимствование из этого поста , ниже приведен пример использования моей работающей функции.

# The function
def newEntropy(x):
    A = x

    pA = A / A.sum()
    Shannon2 = -np.nansum(pA * np.log2(pA))

    return Shannon2

# Make fake data
df = pd.DataFrame(np.random.rand(20,5), columns=list('abcde'))
df['group'] = [0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5]
df['group2'] = [6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10]

# Works
df.groupby(['group', 'group2']).apply(newEntropy)

# Having an index column that is a string causes failure
df['group2'] = df['group2'].astype('str')
df.groupby(['group', 'group2']).apply(newEntropy)

Мне нужно выяснить, как заставить работать новую энтропию. Кажется, что он должен игнорировать столбцы группировки, но это не так. Я также предпочел бы не конвертировать 'group2' в int64, потому что в моих реальных данных это 'YYYY-MM-DD'. Мои данные, эквивалентные 'group1', также являются названием страны, которое я предпочитаю хранить в виде строк.

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

1 Ответ

1 голос
/ 08 мая 2019

Как конкретно столбец вы хотите apply function после groupby

df.groupby(['group', 'group2'])[list('abcde')].apply(newEntropy)
Out[191]: 
group  group2
0      6         6.057044
       7        -0.000000
1      7         4.485942
2      7         4.879091
       8         3.727744
       9        -0.000000
3      9         4.751447
4      9        -0.000000
       10        8.993928
5      10        4.191522
dtype: float64
...