通过熊猫数据框架有效循环



我有以下我需要帮助的问题。我在一个CSV文件中有310个记录,其中包含有关错误的一些信息。在另一个CSV文件中,我有80万记录,其中包含有关袋子的统计信息(可能导致错误的事件(。

在下面的脚本中,我正在尝试

  1. 循环穿过错误,然后选择一个。
  2. 循环浏览统计记录并检查某些条件
  3. 如果有匹配记录。
  4. 保存新文件

我的问题是,我是否可以使用Numpy或其他任何东西以更有效的方式进行核对。由于统计的大小

,当前的方法需要永远运行

朝着正确方向的任何帮助或技巧都将不胜感激。thanx在Adavance

dataset = pd.read_csv('310_records.csv')
dataset1 = pd.read_csv('800K_records.csv')
cols_error = dataset.iloc[:, [0, 1, 2, 3, 4, 5, 6]]
cols_stats = dataset1.iloc[:, [1, 2, 3, 4, 5, 6, 7, 8, 9]]
cols_stats['Fault'] = ''
cols_stats['Created'] = ''
for i, error in cols_error.iterrows():    
    fault_created = error [0]
    fault_ucs = error [1]
    fault_dn = error [2]
    fault_epoch_end = error [3]
    fault_epoch_begin = error [4]
    fault_code = error [6]    
    for index, stats in cols_stats.iterrows():
        stats_epoch = stats[0]
        stats_ucs = stats[5]        
        stats_dn = stats[7]
        print("error:", i, " Stats:", index)        
        if(stats_epoch >= fault_epoch_begin and stats_epoch <= fault_epoch_end):
            if(stats_dn == fault_dn):
                if(stats_ucs == fault_ucs):
                    cols_stats.iloc[index, 9] = fault_code
                    cols_stats.iloc[index, 10] = fault_created
        else:
            cols_stats.iloc[index, 9] = 0
            cols_stats.iloc[index, 10] = fault_created
cols_stats.to_csv('datasets/dim_stats_error.csv', sep=',', encoding='utf-8')

首先:您确定您的代码可以做您想要的吗?如我所见,您会继续循环介绍统计信息,因此,如果您找到了与错误1的匹配错误,则可以稍后覆盖使用错误#310的统计数据的相应附录。目前尚不清楚您应该在没有匹配的错误事件的统计事件中做什么,但是当前您正在任意任意存储这些数据点的fault_created列。更不用说每次都为每个错误检查每个事件所做的额外工作。

慢跑的原因是您要注意使用熊猫的力量。在Numpy和Pandas中,性能的一部分都来自内存管理,其余来自矢量化。通过将大部分工作从本机Python循环推向矢量化功能(运行编译的代码(,您就可以开始看到巨大的速度改进。

我不确定是否有一种矢量化的高级方法,但是由于您正在查看310 vs 800K项目,因此将循环保持在错误和矢量化内部循环。关键是逻辑索引,您可以使用它立即解决所有800K项目:

for i, error in cols_error.iterrows():
    created, ucs, dn, epoch_end, epoch_begin, _, code = error
    inds = ( (epoch_begin <= cols_stats['epoch']) &
             (cols_stats['epoch'] <= epoch_end) &
             (cols_stats['dn'] == dn) &
             (cols_stats['ucs'] == ucs) )
    cols_stats['Fault'][inds] = code
    cols_stats['Created'][inds] = created
cols_stats.to_csv('datasets/dim_stats_error.csv', sep=',', encoding='utf-8')

请注意,以上不会将无与伦比的列设置为非平凡的东西,因为我认为您的问题中没有合理的例子。无论您要设置的默认值什么都应该独立于错误列表,因此您应该在整个匹配的折磨之前设置这些值。

请注意,我为您的代码做了一些改头换面。您可以使用脱包分配来设置error中的所有这些值,并删除这些变量的前缀,使其更清晰。我们可以处理前缀,因为我们没有为统计数据框架定义单独的变量。

您可以看到,可以根据矢量化的逻辑索引操作来定义给定错误的所有匹配统计项目的条件。所得的PANDAS Series称为inds的统计数据框架的每一行都有一个布尔。这可用于分配给名为'Fault''Created'的列的子集。请注意,您可以(并且可能应该(按名称索引您的列,至少我觉得这是更清晰和方便的。

由于您的 codecreated对于每个错误是标量(可能是字符串(,因此矢量化的分配cols_stats['Fault'][inds] = codecols_stats['Created'][inds] = createdcols_stats的每个索引项目都设置为这些标量。

我相信结果应该与以前相同,但以增加记忆使用的代价更快。

可以在您的初始化中进行进一步的简化,但是没有MCVE,很难说出细节。至少您可以使用切片符号:

cols_error = dataset.iloc[:, :7]
cols_stats = dataset1.iloc[:, 1:10]

但是,您只忽略了几列,在这种情况下,对于drop而言,这些列可能更清楚。例如,如果在dataset中,您有一个名为"垃圾"的第七列,您可以设置

cols_error = dataset.drop('junk', axis=1)

最新更新