Python Pandas 创建一长串要连接的数据框
Posted
技术标签:
【中文标题】Python Pandas 创建一长串要连接的数据框【英文标题】:Python Pandas creating a long list of dataframes to get concatenated 【发布时间】:2017-03-04 01:59:11 【问题描述】:我正在做一个程序,在每次迭代时都会创建一些值(根本没有多少值:每次迭代只有约 50 个值,其中一些是 4-5 个短字符串,但大多数是 2-3 位整数)。大约有 3000 次迭代。
现在,我使用 pandas 数据框来存储给定迭代的约 50 个值,然后将 df 附加到数据框列表 (dflist) 中,一旦完成所有 3K 迭代,我将连接 3K 数据框(因为它们都有相同的列名)使用类似的东西:
df_final = pd.concat(dflist,axis=0)
是否有更好的方法来执行此过程,例如。只需使用 numpy 数组并沿轴 0 附加值,最后将完整的 numpy 数组转换为具有给定列名集的 Pandas 数据框?
我问是因为经过多次迭代(大约 3000 次迭代中的 200 次),代码速度大幅下降,系统内存使用率缓慢上升,据我所知,在迭代之间,我的所有值都被覆盖除了这个熊猫数据框列表之外的每次迭代,这似乎是每次迭代后唯一增长的东西。我正在使用 Python 2.7。当我在 Spyder GUI 中或仅从命令行运行我的脚本时,就会发生这种行为。
另一件事:尽管我实际保存的值相对较小(每次迭代大约 50 个值),但我提取这些汇总值所经过的数据非常大。所以原始的 csv 大约是 10 GB,有大约 2 亿行,我使用 pd.read_csv 对它进行分块,给定的块大小约为 50K 行。然后对于这 50K 行,我得到大约 50 个值。但我原以为每个块都是独立的,并且由于值被覆盖,内存使用量不应该像现在这样增长。
例子df:
CHFAC Bygoper Change MinB NumB NumCombos Total
0 abc3 574936022 + 1 1 1 11
1 abc3 574936022 - 1 0 0 0
2 abc3 574936022 + 2 1 1 11
3 abc3 574936022 - 2 0 0 0
4 abc3 574936022 + 5 1 1 11
5 abc3 574936022 - 5 0 0 0
6 abc3 574936022 + 10 1 1 11
7 abc3 574936022 - 10 0 0 0
【问题讨论】:
向我们展示你是 concat 的一到两个示例 df,根据你的帖子很难判断你有多少列、索引等。 【参考方案1】:您可以发挥创造力并使用列表来存储数据,然后在循环结束时创建最终数据框。很难使用您的示例,因为我们对您的创建过程一无所知。我将给出一个通用答案,显示基于 10 次迭代的循环创建 2 列数据框,其中每次迭代都有不同的输出长度
import pandas as pd
from random import randint
col1_val, col2_val = [], []
for i in range(10):
random_len = range(randint(0, 9))
col1 = random_len
col2 = random_len
col1_val.extend(col1)
col2_val.extend(col2)
pd.DataFrame('col1':col1_val, 'col2':col2_val)
输出[110]:
col1 col2
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 0 0
6 1 1
7 2 2
8 3 3
现在让我们看看速度,使用列表方法:
import time
st = time.time()
col1_val, col2_val = [], []
for i in range(10000):
random_len = range(randint(0, 9))
col1 = random_len
col2 = random_len
col1_val.extend(col1)
col2_val.extend(col2)
pd.DataFrame('col1':col1_val, 'col2':col2_val)
print time.time()-st
0.0499999523163
使用你的方法:
st = time.time()
dflist = []
for i in range(10000):
random_len = range(randint(0, 9))
col1 = random_len
col2 = random_len
dflist.append(pd.DataFrame('col1':col1, 'col2':col2))
pd.concat(dflist)
print time.time()-st
7.21199989319
所以对于 10000 次迭代,它会快大约 180 倍
【讨论】:
好的,这应该是对当前附加到数据帧列表的方法的改进。那么您提出的扩展列的方法的性能差异是什么: col1_val.extend(col1) 与一次将所有这些值附加到 numpy 数组?例如。 vals = np.vstack((vals,[1,2])) 用于 2 列示例? @sambajetson 扩展或附加一个 numpy 数组在内存方面不是很有效,我不建议这样做。你可以read this answer 举例说明为什么你不应该那样处理它以上是关于Python Pandas 创建一长串要连接的数据框的主要内容,如果未能解决你的问题,请参考以下文章