У меня есть функция, которая возвращает единичный 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()
@jpp: Не могли бы вы посоветовать, как лучше всего поделиться кодом? это очень длинный код; В настоящее время я пытаюсь написать пример функции, которая производит аналогичный вывод, чтобы мы могли попробовать ее в цикле, пожалуйста, терпите меня
Это сложный вопрос. Вам нужно будет проделать некоторую работу, чтобы предоставить минимальный воспроизводимый пример. Это может занять некоторое время, но оно потрачено не зря.
@jpp: я создал две версии: одну оригинальную (сначала неэффективный pd.DataFrame, а затем список) и вторую (попытка перейти на список / массив, а затем сделать pd.DataFrame). Когда я запускаю их, я получаю те же ошибки, что и при запуске исходного кода.






Ваша идея вернуть список фреймов данных, а затем добавить их или добавить результат через цикл неэффективна.
Вместо этого я советую вам вывести список списков, а затем создать фрейм данных за один шаг.
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?
В этом случае вам необходимо предоставить некоторые данные, чтобы мы могли воспроизвести вашу ошибку. Например, редактировать ваш вопрос со списком списков (например, 10 строк), и тогда мы сможем увидеть, в чем проблема.
спасибо, на самом деле я мог взять все переменные и сделать их скаляром, как вы сделали с datetime, pd.Series.values. Вернусь как можно скорее
он работает так, как вы предложили! Теперь у цикла есть еще одна проблема для функции, которая использует фреймы данных подмножества для создания списка кортежей stackoverflow.com/questions/49909524/…
У вас есть не список списков, это список фреймов данных. Вам нужно изменить свою функцию, чтобы она возвращала список. Поскольку вы не поделились этим кодом для
func, мы не можем помочь решить проблему.