У меня есть программа с вложенной структурой, которая в настоящее время написана с использованием очевидного подхода для добавления списка списков к верхнему уровню DataFrame
(путем создания DataFrame
из этого списка списков и затем добавив это к цели DataFrame
):
import pandas as pd
columns=["inner", "outer", "col1", "col2", "col3", "col4"]
def create_children(inner, outer):
results = []
for i in range(inner):
results.append([f'{i}', f'{outer}', 'a', 'b', 'c', 'd'])
return results
def test(outer, inner):
df = pd.DataFrame(columns=columns)
for i in range(outer):
children = create_children(inner, i)
child_df = pd.DataFrame(children, columns=columns)
df = pd.concat([df, child_df]) # Faster than append
return df
Проблема в том, что когда я профилирую это, создание дочернего элемента DataFrame
занимает серьезное количество времени:
Timer unit: 1e-06 s
Total time: 0.012352 s
File: <ipython-input-43-d816d566eb1b>
Function: test at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def test(outer, inner):
2 1 5542.0 5542.0 44.9 df = pd.DataFrame(columns=columns)
3 3 5.0 1.7 0.0 for i in range(outer):
4 2 10.0 5.0 0.1 children = create_children(inner, i)
5 2 4341.0 2170.5 35.1 child_df = pd.DataFrame(children, columns=columns)
6 2 2454.0 1227.0 19.9 df = pd.concat([df, child_df])
7 # Works in this case but problems with an index and slightly slower
8 # df = df.append(child_df)
9
10 1 0.0 0.0 0.0 return df
Если я переписываю этот простой пример для создания только DataFrame
в конце, то он значительно быстрее:
def test2(outer, inner):
all_children = []
for i in range(outer):
children = create_children(inner, i)
all_children.extend(children)
df = pd.DataFrame(all_children, columns=columns)
return df
Предоставление:
Timer unit: 1e-06 s
Total time: 0.002104 s
File: <ipython-input-44-05d8d95dfe60>
Function: test2 at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def test2(outer, inner):
2 1 1.0 1.0 0.0 all_children = []
3 3 4.0 1.3 0.2 for i in range(outer):
4 2 8.0 4.0 0.4 children = create_children(inner, i)
5 2 2.0 1.0 0.1 all_children.extend(children)
6
7 1 2088.0 2088.0 99.2 df = pd.DataFrame(all_children, columns=columns)
8
9 1 1.0 1.0 0.0 return df
К сожалению, рассматриваемая программа использует DataFrame
функции во внешнем l oop, поэтому я не могу просто исключить использование DataFrame
. (Моя конечная цель - сделать это, но это довольно трудоемкий рефакторинг.)
Мой вопрос таков: есть ли способ добавить соответствующий список списков в DataFrame
без создания промежуточный DataFrame
, что, по-видимому, влечет за собой большие накладные расходы?