2015-07-28 3 views
19

У меня есть следующий цикл:Как добавить строки в кадре данных pandas в цикле for?

for i in links: 
    data = urllib2.urlopen(str(i)).read() 
    data = json.loads(data) 
    data = pd.DataFrame(data.items()) 
    data = data.transpose() 
    data.columns = data.iloc[0] 
    data = data.drop(data.index[[0]]) 

Каждый dataframe создал, таким образом имеет большинство столбцов общих с другими, но не все из них. Более того, все они имеют только один ряд. То, что мне нужно, это добавить к кадру данных все отдельные столбцы и каждую строку из каждого кадра данных, созданного контуром цикла

Я пробовал совместное использование панд или подобное, но ничего не работало. Есть идеи? Благодарю.

ответ

20

Предположим, что ваши данные выглядит следующим образом:

import pandas as pd 
import numpy as np 

np.random.seed(2015) 
df = pd.DataFrame([]) 
for i in range(5): 
    data = dict(zip(np.random.choice(10, replace=False, size=5), 
        np.random.randint(10, size=5))) 
    data = pd.DataFrame(data.items()) 
    data = data.transpose() 
    data.columns = data.iloc[0] 
    data = data.drop(data.index[[0]]) 
    df = df.append(data) 
print('{}\n'.format(df)) 
# 0 0 1 2 3 4 5 6 7 8 9 
# 1 6 NaN NaN 8 5 NaN NaN 7 0 NaN 
# 1 NaN 9 6 NaN 2 NaN 1 NaN NaN 2 
# 1 NaN 2 2 1 2 NaN 1 NaN NaN NaN 
# 1 6 NaN 6 NaN 4 4 0 NaN NaN NaN 
# 1 NaN 9 NaN 9 NaN 7 1 9 NaN NaN 

Тогда можно было бы заменить

np.random.seed(2015) 
data = [] 
for i in range(5): 
    data.append(dict(zip(np.random.choice(10, replace=False, size=5), 
         np.random.randint(10, size=5)))) 
df = pd.DataFrame(data) 
print(df) 

Другими словами, не образуют новый DataFrame для каждой строки. Вместо этого собирайте все данные в списке dicts, а затем вызывайте df = pd.DataFrame(data) один раз в конце, вне цикла.

Для каждого вызова df.append требуется выделить пространство для нового DataFrame с одной дополнительной строкой, скопировав все данные из исходного DataFrame в новый DataFrame и затем скопировав данные в новую строку. Все, что распределение и копирование делает вызов df.append в цикле очень неэффективным. Временная стоимость копирования растет квадратично с количеством строк. Не только код вызова-DataFrame-once легче писать, но и производительность будет намного лучше - временная стоимость копирования растет линейно с количеством строк.

+2

Я был очень удивлен разницей в производительности: добавление 100 строк из 5 значений принимает 336ms с dataframe.append (я пробовал dataframe.loc [i], кажется, что то же самое) То же, что и предлагаемое решение, 4.8 мс! –

11

Есть две причины, по которым вы можете добавить строки в цикле: 1. добавить к существующему df и 2. создать новый df.

создать новую Д.Ф., я думаю, что его хорошо документирована, что вы должны либо создать свои данные в виде списка, а затем создать фрейм данных:

cols = ['c1', 'c2', 'c3'] 
lst = [] 
for a in range(2): 
    lst.append([1, 2, 3]) 
df1 = pd.DataFrame(lst, columns=cols) 
df1 
Out[3]: 
    c1 c2 c3 
0 1 2 3 
1 1 2 3 

ИЛИ Создать dataframe с индексом, а затем добавить к нему

cols = ['c1', 'c2', 'c3'] 
df2 = pd.DataFrame(columns=cols, index=range(2)) 
for a in range(2): 
    df2.loc[a].c1 = 4 
    df2.loc[a].c2 = 5 
    df2.loc[a].c3 = 6 
df2 
Out[4]: 
    c1 c2 c3 
0 4 5 6 
1 4 5 6 

Если вы хотите добавить к существующему dataframe, вы можете использовать любой метод выше, а затем добавьте вместе ДФ в (с или без индекса):

df3 = df2.append(df1, ignore_index=True) 
df3 
Out[6]: 
    c1 c2 c3 
0 4 5 6 
1 4 5 6 
2 1 2 3 
3 1 2 3 

Или вы также можете создать список словарных статей и добавить те, что указаны в ответе выше.

lst_dict = [] 
for a in range(2): 
    lst_dict.append({'c1':2, 'c2':2, 'c3': 3}) 
df4 = df1.append(lst_dict) 
df4 
Out[7]: 
    c1 c2 c3 
0 1 2 3 
1 1 2 3 
0 2 2 3 
1 2 2 3 

Использование Dict (ZIP (COLS, Vals)))

lst_dict = [] 
for a in range(2): 
    vals = [7, 8, 9] 
    lst_dict.append(dict(zip(cols, vals))) 
df5 = df1.append(lst_dict) 
0

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

Следовательно, мне нужно переместить содержимое фрейма данных в пустой фрейм данных, который был создан уже. Это так просто. Нам просто нужно использовать.добавить функцию, как показано ниже:

temp_df = pd.DataFrame() #Temporary empty dataframe 
for sent in Sentences: 
    New_df = pd.DataFrame({'words': sent.words}) #Creates a new dataframe and contains tokenized words of input sentences 
    temp_df = temp_df.append(New_df, ignore_index=True) #Moving the contents of newly created dataframe to the temporary dataframe 

Вне для цикла, вы можете скопировать содержимое временного кадра данных в кадр основных данных, а затем удалить временную рамку данных, если она не нужна

Смежные вопросы