我有以下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,但似乎没有任何效果。任何的想法?感谢。
答案 0 :(得分:51)
假设您的数据如下所示:
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
的效率非常低。使用行数复制grows quadratically的时间成本。 call-DataFrame-once代码不仅更易于编写,而且性能也会更好 - 复制的时间成本与行数呈线性增长。
答案 1 :(得分:43)
有两个原因可以在循环中追加行,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
OR,使用索引创建数据框,然后添加到其中
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)
答案 2 :(得分:4)
我在临时空数据框的帮助下在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循环之外,您可以将临时数据框的内容复制到主数据框中,然后删除临时数据框(如果您不需要)
答案 3 :(得分:1)
更紧凑,更有效的方法可能是:
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