Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我必须将Pandas数据帧中每一行的数据与其余行的数据进行比较,有没有办法加快计算速度?_Python_Pandas_Performance_Dataframe_Optimization - Fatal编程技术网

Python 我必须将Pandas数据帧中每一行的数据与其余行的数据进行比较,有没有办法加快计算速度?

Python 我必须将Pandas数据帧中每一行的数据与其余行的数据进行比较,有没有办法加快计算速度?,python,pandas,performance,dataframe,optimization,Python,Pandas,Performance,Dataframe,Optimization,假设我有一个pandas数据框(从csv文件加载)具有这种结构(var和err列的数量不是固定的,并且它随文件而异): 为了这个问题,让我们放弃err_ds_j和err_mean列。 我必须对每一行的值与其他行的值进行自动比较;例如:我必须将第一行与第二行、第三行、第四行进行比较,依此类推,然后我必须将第二行与第一行进行比较,然后与第三行进行比较,依此类推数据帧的其余部分 深入研究这个问题,我想看看对于每两行,其中一行的所有“var_I”值是否高于或等于另一行的对应值。如果满足此条件,则具有更高

假设我有一个pandas数据框(从csv文件加载)具有这种结构(var和err列的数量不是固定的,并且它随文件而异):

为了这个问题,让我们放弃err_ds_j和err_mean列。 我必须对每一行的值与其他行的值进行自动比较;例如:我必须将第一行与第二行、第三行、第四行进行比较,依此类推,然后我必须将第二行与第一行进行比较,然后与第三行进行比较,依此类推数据帧的其余部分

深入研究这个问题,我想看看对于每两行,其中一行的所有“var_I”值是否高于或等于另一行的对应值。如果满足此条件,则具有更高值的行称为主导行,我在另一个数据帧中添加一行,其结构如下:

SET_A; SET_B; DOMINANT_SET
0;     1;     B
...
其中SET_A和SET_B值是来自csv数据帧的索引,主控_SET告诉我这两个值中的哪一个是主控集(或者如果没有,则只指定为“无”)。 我发现第三列很有用,因为它可以帮助我避免以相反的方式比较我已经比较过的行(例如:比较第1行和第0行是无用的,因为我之前已经比较过0和1)

因此,对于该csv文件,生成的输出应该是(实际上是,使用我的代码):

我已经为这个特定的问题编写了所有的代码,对于一些测试数据集(从实际数据集中采样100行)来说,它工作得很好

以下是相关代码的片段:

将numpy导入为np
作为pd进口熊猫
已测试def耦合(index1、index2、数据帧):
返回((数据帧['SET_A']==index1)和(数据帧['SET_B']==index2)).any());((数据帧['SET_A']==index2)和(数据帧['SET_B']==index1)).any())
def检查优势(集合a、集合b、索引i、索引j、数据帧):
长度=数据帧。形状[0]
如果np.all(集合a>=集合b):
打印(“发现主配置A>B”)
dataframe.loc[length+1]=[index_i,index_j,'A']
elif np.all(集合b>=集合a):
打印(“发现主配置B>A”)
dataframe.loc[length+1]=[index_i,index_j,'B']
其他:
dataframe.loc[length+1]=[index_i,index_j,'none']
df=pd.read_csv('test.csv',sep=';')
dom_table_df=pd.DataFrame(列=['SET_A'、'SET_B'、'magnific_SET'])
df_长度=df.形状[0]
var_num=df.shape[1]-1
a=无
b=无
对于范围内的i(0,df_长度):
a=df.iloc[i,0:var_num].值
对于范围内的j(0,df_长度):
如果j==i:
持续
b=df.iloc[j,0:var_num]。值
如果已对耦合进行测试(i、j、dom表df):
打印(“警告:配置”,i,j,“已比较,跳过”)
其他:
打印(“将第i行的配置与第j行的配置进行比较”)
检查优势(a、b、i、j、dom\U表\U df)
打印(dom\u table\u df)
问题是,由于python和pandas都不太精通(我已经学习了大约一个半月),这段代码当然非常慢(对于1000到10000行的数据集),因为我在算法中使用迭代。我知道我可以使用一种称为矢量化的方法,但在阅读有关它的文章时,我并不完全确定这是否适合我的用例


那么,我如何加快计算速度呢?

这不是算法的主要变化,但是如果你充分选择
j
的范围,你可以节省一半以上的循环周期以及
j==I
couple\u已经测试过的
,那么主循环就变成:

for i in range(0, df_length):
    a = df.iloc[i, 0:var_num].values
    for j in range(i+1, df_length): # we can skip the range from 0 to i
        b = df.iloc[j, 0:var_num].values
        #print("Comparing configuration at row", i, "with configuration at row", j)
        check_dominance(a, b, i, j, dom_table_df)
另一个(令人惊讶的)显著的加速可以通过预分配输出数据帧而不是一行接一行地追加来实现。我们可以将结果行数计算为

  • (df_长度2− df_长度)÷2
为了确定插入当前输出数据集的行号,我们现在可以维护一个计数器,而不是
dataframe.shape[0]
。这使得:

dom_table_df = pd.DataFrame(index=np.arange(1, 1+(df_length**2-df_length)/2).astype('i'),
                            columns=['SET_A', 'SET_B', 'DOMINANT_SET'])
length = 0  # counter of already filled rows
for i in range(0, df_length):
    a = df.iloc[i, 0:var_num].values
    for j in range(i+1, df_length): # we can skip the range from 0 to i
        b = df.iloc[j, 0:var_num].values
        #print("Comparing configuration at row", i, "with configuration at row", j)
        length += 1
        if np.all(a >= b):
            #print("FOUND DOMINANT CONFIGURATION A > B")
            dom_table_df.loc[length] = [i, j, 'A']
        elif np.all(b >= a):
            #print("FOUND DOMINANT CONFIGURATION B > A")
            dom_table_df.loc[length] = [i, j, 'B']
        else:
            dom_table_df.loc[length] = [i, j, 'none']

另一个加速可以通过将
.iloc[].values
以及
.loc[]
替换为
.values[]
来实现,但是使用
.loc[]
我们必须调整下标,因为
.values
采用零下标,这不同于我们基于1的
dom\u table\u.index

dom_table_df = pd.DataFrame(index=np.arange(1, 1+(df_length**2-df_length)/2).astype('i'),
                            columns=['SET_A', 'SET_B', 'DOMINANT_SET'])
length = 0  # counter of already filled rows
for i in range(0, df_length):
    a = df.values[i, 0:var_num]
    for j in range(i+1, df_length): # we can skip the range from 0 to i
        b = df.values[j, 0:var_num]
        #print("Comparing configuration at row", i, "with configuration at row", j)
        if np.all(a >= b):
            #print("FOUND DOMINANT CONFIGURATION A > B")
            dom_table_df.values[length] = [i, j, 'A']
        elif np.all(b >= a):
            #print("FOUND DOMINANT CONFIGURATION B > A")
            dom_table_df.values[length] = [i, j, 'B']
        else:
            dom_table_df.values[length] = [i, j, 'none']
        length += 1

看看
drop\u duplicates
是否对您有用谢谢您的反馈,mohanys,我已经用您的建议编辑了我的问题,现在我将研究drop\u duplicates。再次感谢您的建议和您的时间,不幸的是,drop\u duplicates可能不适合我的问题,因为我的问题可能在for循环中,这是一个嵌套循环(如果我错了,请纠正我,但复杂度应该是O(n^2),这对于10000行数据集来说很糟糕)。旁注:根据定义,如果两行相等,则两行可以同时占主导地位,但是在这种情况下,该算法只会产生
A
。谢谢你的提醒,阿玛利!事实上这是一个疏忽,但它不会影响整个分析。哇!这肯定会在一定程度上加快进程,谢谢!我还将尝试寻找方法来并行化循环的各个部分,以进一步提高速度。嗯,为什么不将所有3个答案都放在一个上?因为每个部分本身都是一个离散优化。好吧,这真是太疯狂了,这一个以及其他两个建议让我在2分钟内而不是12小时内运行了1000行数据集。我真不知道该怎么感谢你才好!
dom_table_df = pd.DataFrame(index=np.arange(1, 1+(df_length**2-df_length)/2).astype('i'),
                            columns=['SET_A', 'SET_B', 'DOMINANT_SET'])
length = 0  # counter of already filled rows
for i in range(0, df_length):
    a = df.iloc[i, 0:var_num].values
    for j in range(i+1, df_length): # we can skip the range from 0 to i
        b = df.iloc[j, 0:var_num].values
        #print("Comparing configuration at row", i, "with configuration at row", j)
        length += 1
        if np.all(a >= b):
            #print("FOUND DOMINANT CONFIGURATION A > B")
            dom_table_df.loc[length] = [i, j, 'A']
        elif np.all(b >= a):
            #print("FOUND DOMINANT CONFIGURATION B > A")
            dom_table_df.loc[length] = [i, j, 'B']
        else:
            dom_table_df.loc[length] = [i, j, 'none']
dom_table_df = pd.DataFrame(index=np.arange(1, 1+(df_length**2-df_length)/2).astype('i'),
                            columns=['SET_A', 'SET_B', 'DOMINANT_SET'])
length = 0  # counter of already filled rows
for i in range(0, df_length):
    a = df.values[i, 0:var_num]
    for j in range(i+1, df_length): # we can skip the range from 0 to i
        b = df.values[j, 0:var_num]
        #print("Comparing configuration at row", i, "with configuration at row", j)
        if np.all(a >= b):
            #print("FOUND DOMINANT CONFIGURATION A > B")
            dom_table_df.values[length] = [i, j, 'A']
        elif np.all(b >= a):
            #print("FOUND DOMINANT CONFIGURATION B > A")
            dom_table_df.values[length] = [i, j, 'B']
        else:
            dom_table_df.values[length] = [i, j, 'none']
        length += 1