[英]How to append rows in a pandas dataframe in a for loop?
我有以下 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]])
如此創建的每個數據幀都具有與其他數據幀相同的大多數列,但不是全部。 而且,它們都只有一排。 我需要做的是將 for 循環生成的每個數據框中的所有不同列和每一行添加到數據框中
我嘗試了 pandas concatenate 或類似的方法,但似乎沒有任何效果。 任何的想法? 謝謝。
假設您的數據如下所示:
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。 相反,收集字典列表中的所有數據,然后在循環外的末尾調用df = pd.DataFrame(data)
一次。
每次調用df.append
需要為具有額外一行的新 DataFrame 分配空間,將原始 DataFrame 中的所有數據復制到新 DataFrame 中,然后將數據復制到新行中。 所有這些分配和復制使得在循環中調用df.append
非常低效。 復制的時間成本與行數成二次方增長。 call-DataFrame-once 代碼不僅更容易編寫,其性能也會好得多——復制的時間成本隨行數線性增長。
您可以在循環中追加行的原因有兩個,1. 添加到現有的 df,以及 2. 創建一個新的 df。
要創建一個新的 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
或者,使用索引創建數據框,然后添加到它
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
如果要添加到現有數據幀,可以使用上述任一方法,然后將 df 附加在一起(帶或不帶索引):
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)
包括以下評論中的想法:
事實證明 Pandas 確實有一種有效的方法來附加到數據幀:
df.loc( len(df) ) = [new, row, of, data]
(this) 將就地“附加”到數據幀的末尾。 – Demis 3 月 22 日 15:32
一種更緊湊和有效的方法可能是:
cols = ['frame', 'count']
N = 4
dat = pd.DataFrame(columns = cols)
for i in range(N):
dat = dat.append({'frame': str(i), 'count':i},ignore_index=True)
輸出將是:
>>> dat
frame count
0 0 0
1 1 1
2 2 2
3 3 3
我在臨時空數據框的幫助下在 for 循環中創建了一個數據框。 因為對於 for 循環的每次迭代,都會創建一個新的數據框,從而覆蓋前一次迭代的內容。
因此,我需要將數據框的內容移動到已經創建的空數據框。 就這么簡單。 我們只需要使用 .append 函數,如下所示:
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
在for循環之外,可以將臨時數據框的內容復制到主數據框內,不需要時刪除臨時數據框
首先,創建一個帶有列名的空 DataFrame,之后,在 for 循環中,您必須定義一個包含要追加的數據的字典(一行):
df = pd.DataFrame(columns=['A'])
for i in range(5):
df = df.append({'A': i}, ignore_index=True)
df
A
0 0
1 1
2 2
3 3
4 4
如果要添加具有更多列的行,代碼將如下所示:
df = pd.DataFrame(columns=['A','B','C'])
for i in range(5):
df = df.append({'A': i,
'B': i * 2,
'C': i * 3,
}
,ignore_index=True
)
df
A B C
0 0 0 0
1 1 2 3
2 2 4 6
3 3 6 9
4 4 8 12
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.