Поэлементное деление с накопленными числами в Python? - PullRequest
1 голос
/ 16 октября 2019

Заголовок может показаться запутанным (честно говоря, я не совсем уверен, как его обобщить в предложении), поэтому вот гораздо лучшее объяснение:

В настоящее время я работаю с фреймом данных A относительно различных атрибутов, и я использовал функцию .groupby[].count() для столбца данных age, чтобы создать список вхождений:

A_sub = A.groupby(['age'])['age'].count()

A_sub возвращает серию, аналогичную следующей (значения изменяются случайным образом):

age
1    316
2    249
3    221
4    219
5    262
...
59    1
61    2
65    1
70    1
80    1
Name: age, dtype: int64

Я хотел бы построить список значений из поэлементного деления. Деление, которое я хотел бы выполнить, представляет собой значение элемента, деленное на сумму всех элементов, индекс которых больше или равен этому элементу. Другими словами, например, для возраста 3 он должен возвращать

221/(221+219+262+...+1+2+1+1+1)

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

Ответы [ 3 ]

1 голос
/ 16 октября 2019

Вы можете использовать функцию cumsum() в пандах, чтобы получить накопленные суммы:

A_sub = A['age'].value_counts().sort_index(ascending=False)
(A_sub / A_sub.cumsum()).iloc[::-1]
1 голос
/ 16 октября 2019

Нет причин использовать numpy, панды уже включают все, что нам нужно.

A_sub, кажется, возвращает Серию, где age - индекс. Это не идеально, но должно быть хорошо. Поэтому приведенный ниже код работает с сериями, но его легко изменить для работы с фреймами данных.

import pandas as pd

s = pd.Series(data=np.random.randint(low=1, high=10, size=10), index=[0, 1, 3, 4, 5, 8, 9, 10, 11, 13], name="age")
print(s)

res = s / s[::-1].cumsum()[::-1]
res = res.rename("cumsum div")

Я видел ваш комментарий об отсутствующих возрастах в индексе. Вот как вы должны добавить отсутствующие индексы в диапазоне от минимального до максимального индекса, а затем выполнить деление.

import pandas as pd

s = pd.Series(data=np.random.randint(low=1, high=10, size=10), index=[0, 1, 3, 4, 5, 8, 9, 10, 11, 13], name="age")

s_all_idx = s.reindex(index=range(s.index.min(), s.index.max() + 1), fill_value=0)
print(s_all_idx)

res = s_all_idx / s_all_idx[::-1].cumsum()[::-1]
res = res.rename("all idx cumsum div")
1 голос
/ 16 октября 2019

Вот краткий пример использования numpy. Аналогичный подход можно использовать с пандами. Цикл for, скорее всего, можно заменить чем-то более умным и более эффективным для вычисления коэффициентов.

import numpy as np

ages = np.asarray([316, 249, 221, 219, 262])
coefficients = np.zeros(ages.shape)

for k, a in enumerate(ages):
    coefficients[k] = sum(ages[k:])

output = ages / coefficients

Вывод:

array([0.24940805, 0.26182965, 0.31481481, 0.45530146, 1.        ])

РЕДАКТИРОВАТЬ: коэффициенты инициализации на 0 и цикл for можно заменить на:

coefficients = np.flip(np.cumsum(np.flip(ages)))
...