Объединить строки в pandas
Не хватает пока знаний в pandas разобраться самому. Нужно сгруппировать данные по дням так, чтобы из таблицы типа:
Day A B C
1 2019-12-10 5 4 1
2 2019-12-10 3 1 6
3 2019-12-11 1 5 2
4 2019-12-11 3 3 6
получилось так:
Day A B C A1 B1 C1
1 2019-12-10 5 4 1 3 1 6
2 2019-12-11 1 5 2 3 3 6
Значения разнятся в зависимости от времени получения в течении одного дня.
Реальные данные:
Time Open High Low Close Volume
0 2019-12-30 1.12026 1.12051 1.12026 1.12036 189
1 2019-12-30 1.12036 1.12037 1.12014 1.12027 193
2 2019-12-30 1.12027 1.12029 1.12023 1.12029 113
3 2019-12-31 1.12027 1.12028 1.12003 1.12006 217
4 2019-12-31 1.12006 1.12021 1.12005 1.12019 143
Ответы (2 шт):
Предположим, есть датафрейм:
import pandas as pd
df = pd.DataFrame({"Day":["2019-12-10", "2019-12-10", "2019-12-11", "2019-12-11"],
"A":[5,3,1,3],
"B":[4, 1, 5, 3],
"C":[1,6,2,6]})
Day A B C
0 2019-12-10 5 4 1
1 2019-12-10 3 1 6
2 2019-12-11 1 5 2
3 2019-12-11 3 3 6
Тогда:
df1 = df.groupby('Day').aggregate(lambda x: list(x)).reset_index()
res = df1.iloc[:,:1]
for col in df1.columns[1:]:
res = res.join(pd.DataFrame(df1[col].to_list(),
columns=[col+str(x) for x in range(1, len(df1.columns)-1)]))
получаем res:
Day A1 A2 B1 B2 C1 C2
0 2019-12-10 5 3 4 1 1 6
1 2019-12-11 1 3 5 3 2 6
Мне кажется, что это немного неуклюжее решение, но ничего более оптимального пока в голову не приходит.
Базовая задача для этого случая - преобразование таблицы из широкого формата в длинный, см. Wide and narrow data. Обычно в этом контексте упоминается melt, но в данном случае лучше подойдет unstack - разворот индекса строк на последний уровень индекса столбцов. Этим разворотом вы превращаете широкую таблицу каждой группы в длинную последовательность с двухуровневым индексом, которую располагаете вдоль строк новой таблицы:
df = pd.DataFrame({
'Day': ['2019-12-10', '2019-12-10', '2019-12-11', '2019-12-11'],
'A': [5, 3, 1, 3],
'B': [4, 1, 5, 3],
'C': [1, 6, 2, 6]}
)
print(
df
.set_index('Day')
.groupby(level=0)
.apply(lambda df: df.reset_index(drop=True).unstack())
.sort_index(axis='columns', level=-1)
)
# A B C A B C
# 0 0 0 1 1 1
# Day
# 2019-12-10 5 4 1 3 1 6
# 2019-12-11 1 5 2 3 3 6
Перед применением этого подхода нужно убедиться, что строки в пределах каждой группы расположены в правильном порядке. Также важно понимать, что для неравномерно заполненных групп, как в предоставленном вами примере с тремя записями для 2019-12-30 и двумя для 2019-12-31, практически невозможно восстановить правильное положение пропущенных данных. Если у вас 3 временные точки для замера данных и, например, пропущен второй замер, то после удаления времени невозможно понять правильное расположение двух замеров в трех колонках.