from io import BytesIO
from csv import writer
import pandas as pd
output = BytesIO()
csv_writer = writer(output)
for row in iterable_object:
csv_writer.writerow(row)
output.seek(0) # we need to get back to the start of the BytesIO
df = pd.read_csv(output)
return df
# Dictionary containing the data
dic = {'row_1':['some','test','values',78,90],'row_2':['some','test','values',100,589]}
# Creation of the dataframe
df = pd.DataFrame.from_dict(dic,orient='index')
df
0 1 2 3 4
row_1 some test values 78 90
row_2 some test values 100 589
%%timeit
test = pd.DataFrame({"A": [1,2,3], "B": [1,2,3], "C": [1,2,3]})
for i in range(0,1000):
testrow = pd.DataFrame([0,0,0])
pd.concat([test[:1], testrow, test[1:]])
2.15 s ± 88 ms/循环(7次运行的平均值±标准差,每次运行1个循环)
%%timeit
test = pd.DataFrame({"A": [1,2,3], "B": [1,2,3], "C": [1,2,3]})
for i in range(0,1000):
test2 = pd.DataFrame({'A': 0, 'B': 0, 'C': 0}, index=[i+0.5])
test.append(test2, ignore_index=False)
test.sort_index().reset_index(drop=True)
972 ms ± 14.4 ms/循环(7次运行的平均值±标准差,每次运行1个循环)
%%timeit
test = pd.DataFrame({"A": [1,2,3], "B": [1,2,3], "C": [1,2,3]})
for i in range(0,1000):
test3 = [0,0,0]
test.loc[i+0.5] = test3
test.reset_index(drop=True)
1.13 s ± 46 ms/循环(7次运行的平均值±标准差,每次运行1个循环) 当然,这纯粹是综合性的,我承认我没有预料到这些结果,但是看起来在索引不存在的情况下.loc和.append的表现非常相似。
8条答案
按热度按时间lg40wkob1#
我使用了这个答案的
df.loc[i] = [new_data]
建议,但是我有〉500,000行,这非常慢。虽然给出的答案对OP的问题很好,但我发现在处理大量行时(而不是OP所描述的欺骗),使用csvwriter将数据添加到内存中的CSV对象,然后最后使用
pandas.read_csv(csv)
生成所需的DataFrame输出会更有效。对于大约500,000行,速度提高了1000倍,并且随着行数的增加,速度提高只会更大(相比之下,
the df.loc[1] = [data]
将慢得多)希望这能帮助那些在处理比OP更多的行时需要效率的人。
jogvjijk2#
由于选择的答案完全错误,请在此处编辑。下面是对为什么不应使用放大设置的解释。“放大设置”实际上比追加更糟糕。
这里的tl;dr是**没有有效的方法可以使用DataFrame来实现这一点,所以如果您需要速度,应该使用另一种数据结构。**请参阅其他答案以获得更好的解决方案。
更多关于放大设置的信息
您可以使用
loc
在不存在的索引上向DataFrame添加行,但这也会执行所有数据的复制(请参见this discussion)。对于所描述的用例,**放大设置实际上比
append
**多花费50%的时间:使用
append()
时,8000行耗时6.59秒(每行0.8毫秒)使用
.loc()
时,8000行需要10秒(每行1.25毫秒)更长的DataFrame怎么样?
与面向数据代码中的所有分析一样,YMMV和您应该针对您的用例对此进行测试。
append
和“放大设置”的写入时复制行为的一个特征是,使用较大的DataFrame
会变得越来越慢:使用此方法构建16 k行
DataFrame
所需的时间是8 k行的2.3倍。ppcbkaq53#
通过将一行的数据添加到列表中,然后将该列表添加到字典中,您就可以使用
pd.DataFrame.from_dict(dict)
创建一个 Dataframe ,而无需迭代。如果字典的每个值都是一行,则可以只使用:
pd.DataFrame.from_dict(dictionary,orient='index')
小例子:
azpvetkf4#
您需要将问题分为两部分:
1.每30秒有效地接受数据(收集数据)。
1.一旦收集到数据就进行处理。
如果您的数据是关键的(也就是说,您不能丢失它)-将它发送到队列,然后从队列中批量读取它。
队列将提供可靠的(有保证的)接受,并且您的数据不会丢失。
您可以从队列中读取数据并将其转储到数据库中。
现在,Python应用程序只需要从数据库中读取数据,并以任何对应用程序有意义的时间间隔进行分析--也许您想要进行每小时的平均值;在这种情况下,您可以每小时运行一次脚本,从数据库中提取数据,并可能将结果写入另一个数据库/表/文件中。
底线是-将应用程序的收集和分析部分分开。
r6l8ljro5#
假设您的 Dataframe 已按顺序编制索引,您可以:
首先检查下一个索引值是什么以创建新行:
然后使用“at”写入每个所需的列
eqzww0vc6#
我从SQL服务器返回了700K行数据。所有这些对我来说都太长了。下面的方法大大缩短了时间。
这就是我想要的。
nc1teljy7#
2.15 s ± 88 ms/循环(7次运行的平均值±标准差,每次运行1个循环)
972 ms ± 14.4 ms/循环(7次运行的平均值±标准差,每次运行1个循环)
1.13 s ± 46 ms/循环(7次运行的平均值±标准差,每次运行1个循环)
当然,这纯粹是综合性的,我承认我没有预料到这些结果,但是看起来在索引不存在的情况下
.loc
和.append
的表现非常相似。zdwk9cvp8#
我的同事告诉我先做一个字典条目列表,然后把完成的列表推到 Dataframe 中,与一次推一个字典到 Dataframe 相比,列表方法是即时的。
这段代码筛选了大约54k条记录,只查找targ_datetime值之后的记录,然后将所需的值写回列表,再写回df_out: