Суммировать элементы в списке по индексу в цикле

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

def func(input):
     some calculation
     return oneliner

oneliner выглядит так

date         return   return_lev
20100101      0.05      0.0725

Мой цикл теперь создает несколько таких одностраничных строк, и я хотел бы объединить все одинарные строки, если у них одна и та же дата, в противном случае просто добавьте онлайнер:

df = []
for x in range(0, 10)
    res = func(x)
    df.append(res).groupby(by = 'date').sum()

Однако это говорит мне:

AttributeError: 'NoneType' object has no attribute 'groupby'

Даже если вынуть groupby, я получаю ошибку:

AttributeError: 'NoneType' object has no attribute 'sum'

Есть идеи, как я могу это решить?

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

df_date = pd.DataFrame(['20100101', '20100102', 
                    '20100103', '20100104', '20100105'], columns = ['date'])

from random import randint

def test_func(i):
    a = randint(0, 9) + i
    b = randint(0, 9) / 10 + i
    c = randint(0, 9) + i
    d = randint(0, 9) / 10 + i
    datetime = df_date.sample(1)

    a_s = pd.Series(a, dtype = int)
    b_s = pd.Series(b, dtype = float)
    c_s = pd.Series(c, dtype = int)
    d_s = pd.Series(d, dtype = float)

    overview = pd.DataFrame(np.concatenate([a_s, b_s, c_s, d_s]).reshape(1, 4), 
                            columns = ['a', 'b', 'c', 'd'], index = datetime)

    return overview

теперь с моей предыдущей попыткой:

dfs_test = []

for x in range(5):
    test_results = test_func(x)
    dfs_test.append(test_results).groupby(by = 'datetime').sum()

это дает мне, как указано выше

AttributeError: 'NoneType' object has no attribute 'groupby'

теперь с другой версией, где я создаю массив / список:

from random import randint

def test_func_2(i):
    a = randint(0, 9) + i
    b = randint(0, 9) / 10 + i
    c = randint(0, 9) + i
    d = randint(0, 9) / 10 + i
    datetime = df_date.sample(1)

    a_s = pd.Series(a, dtype = int)
    b_s = pd.Series(b, dtype = float)
    c_s = pd.Series(c, dtype = int)
    d_s = pd.Series(d, dtype = float)

    overview = [datetime, a_s, b_s, c_s, d_s]

    return overview

а теперь со списковой версией:

dfs_test_2 = pd.DataFrame([test_func_2(z) for z in range(5)],
                  columns=['datetime', 'a', 'b', 'c', 'd'])

dfs_test_2 = dfs_test_2.groupby('datetime').sum().reset_index()

У вас есть не список списков, это список фреймов данных. Вам нужно изменить свою функцию, чтобы она возвращала список. Поскольку вы не поделились этим кодом для func, мы не можем помочь решить проблему.

jpp 17.04.2018 19:19

@jpp: Не могли бы вы посоветовать, как лучше всего поделиться кодом? это очень длинный код; В настоящее время я пытаюсь написать пример функции, которая производит аналогичный вывод, чтобы мы могли попробовать ее в цикле, пожалуйста, терпите меня

eternity1 17.04.2018 19:43

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

jpp 17.04.2018 19:46

@jpp: я создал две версии: одну оригинальную (сначала неэффективный pd.DataFrame, а затем список) и вторую (попытка перейти на список / массив, а затем сделать pd.DataFrame). Когда я запускаю их, я получаю те же ошибки, что и при запуске исходного кода.

eternity1 18.04.2018 13:48
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
114
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша идея вернуть список фреймов данных, а затем добавить их или добавить результат через цикл неэффективна.

Вместо этого я советую вам вывести список списков, а затем создать фрейм данных за один шаг.

def func(var):
    """Return list of [date, return, return_lev]"""
    # some calculation
    return [a, b, c]

# build dataframe
df = pd.DataFrame([func(x) for x in range(10)],
                  columns=['date', 'return', 'return_lev'])

# perform groupby
df = df.groupby('date').sum().reset_index()

Обновлять: Ваша функция для возврата списка скаляров фактически возвращает список объектов pd.Series.

Попробуйте что-то вроде следующего:

def test_func_2(i):
    a = randint(0, 9) + i
    b = randint(0, 9) / 10 + i
    c = randint(0, 9) + i
    d = randint(0, 9) / 10 + i
    datetime = df_date.sample(1).values[0][0]

    overview = [datetime, a, b, c, d]

    return overview

спасибо за совет по созданию фрейма данных впоследствии. Сборка фрейма данных представляет собой конкатенацию (1x1) pd.Series. Я попытался создать список или массив, похожий на ваше решение. Но при запуске кода я получаю следующую ошибку: DataError: No numeric types to aggregate и TypeError: 'Series' objects are mutable, thus they cannot be hashed, которые, как я полагаю, взяты из моего списка, возвращенного функцией. Полагаю, это из-за pd.Series?

eternity1 17.04.2018 18:40

В этом случае вам необходимо предоставить некоторые данные, чтобы мы могли воспроизвести вашу ошибку. Например, редактировать ваш вопрос со списком списков (например, 10 строк), и тогда мы сможем увидеть, в чем проблема.

jpp 17.04.2018 18:41

спасибо, на самом деле я мог взять все переменные и сделать их скаляром, как вы сделали с datetime, pd.Series.values. Вернусь как можно скорее

eternity1 18.04.2018 15:32

он работает так, как вы предложили! Теперь у цикла есть еще одна проблема для функции, которая использует фреймы данных подмножества для создания списка кортежей stackoverflow.com/questions/49909524/…

eternity1 18.04.2018 23:53

Другие вопросы по теме