Python 优化熊猫代码:替换';iterrows';和其他想法

Python 优化熊猫代码:替换';iterrows';和其他想法,python,pandas,optimization,Python,Pandas,Optimization,我对熊猫不熟悉。我写了一个代码,我想优化,但我不知道如何。我知道“应用”和pandas矢量化都比“ItErrors”快,但不知道如何使用它们来实现相同的目标。iterrows对我来说很简单,因为它类似于“for”循环,所以我已经习惯了。 这是我的密码: import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.metrics import mean_squared_error from

我对熊猫不熟悉。我写了一个代码,我想优化,但我不知道如何。我知道“应用”和pandas矢量化都比“ItErrors”快,但不知道如何使用它们来实现相同的目标。iterrows对我来说很简单,因为它类似于“for”循环,所以我已经习惯了。 这是我的密码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
from scipy.spatial.distance import euclidean
data = pd.read_csv(r'C:\temp\train.txt')

def group_df(df,num):
    ln = len(df)
    rang = np.arange(ln)
    splt = np.array_split(rang,num)
    lst = []
    finel_lst = []
    for i,x in enumerate(splt):
        lst.append([i for x in range(len(x))])
    for k in lst:
        for j in k:
            finel_lst.append(j)
    df['group'] = finel_lst
    return df
def KNN(dafra,folds,K,fi,target):        
    df = group_df(dafra,folds)
    avarge_e = []
    for i in range(folds):
        train = pd.DataFrame(df.loc[df['group'] != i])
        test = pd.DataFrame(df.loc[df['group'] == i])
        test.loc[:,'pred_price'] = np.nan
        test.loc[:,'rmse'] = np.nan
        train.loc[:,'dis'] = np.nan
        train = train.reset_index()
        test = test.reset_index()
        for index,row in test.iterrows():
            for index2,row2 in train.iterrows():
                train.loc[index2]['dis'] = euclidean(row2[fi],row[fi])
如您所见,有两个嵌套的“ItError”循环。顶部还有一个小的“for”循环。 该代码的思想是将每一行测试之间的欧几里德距离分配给每一行列车。但是,由于测试是由“for”循环更改的,它最终将添加到所有原始数据帧中

以下是数据收集:

   Id  MSSubClass MSZoning  LotFrontage  LotArea Street Alley LotShape  \
0   1          60       RL         65.0     8450   Pave   NaN      Reg   
1   2          20       RL         80.0     9600   Pave   NaN      Reg   
2   3          60       RL         68.0    11250   Pave   NaN      IR1   

  LandContour Utilities    ...     PoolArea PoolQC Fence MiscFeature MiscVal  
\
0         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   

1         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   

2         Lvl    AllPub    ...            0    NaN   NaN         NaN       0   

  MoSold YrSold  SaleType  SaleCondition  SalePrice  
0      2   2008        WD         Normal     208500  
1      5   2007        WD         Normal     181500  
2      9   2008        WD         Normal     223500  
[3行x 81列]


任何优化此代码的想法都将受到欢迎。多谢各位

我建议两种可能的解决方案:

-使用scipys

-编写自己的numpy函数

scipy解决方案是直截了当的:

import scipy
import numpy as np

point_vector_1 = np.random.random((10000,2))
point_vector_2 = np.random.random((1000,2))
distance_matrix = scipy.spatial.distance_matrix(point_vector_1, point_vector_2)
在numpy中,我们可以使用外部ufunc来编写我们自己的函数。np.subtract.outer将作为两个向量的矩阵给出,类似于外点积给出的乘法

def euclidean_distance_matrix(vector_1, vector_2):
  dis_dim_1 = np.subtract.outer(vector_1.T[0], vector_2.T[0])**2
  dis_dim_2 = np.subtract.outer(vector_1.T[1], vector_2.T[1])**2
  euclidean = np.sqrt(dis_dim_1+dis_dim_2)
  return euclidean

distance_matrix_2 = euclidean_distance_matrix(point_vector_1, point_vector_2)
时间:

%timeit scipy.spatial.distance_matrix(point_vector_1, point_vector_2)
382 ms ± 8.56 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit euclidean_distance_matrix(point_vector_1, point_vector_2)
150 ms ± 1.33 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
编辑: 要保留原始索引,可以将源df的索引传递到新的数据帧:

dist_array = euclidean_distance_matrix([df1['lat'], df1['long']], [df2['lat'], df2['long']])
df_dist = pd.DataFrame(dist_array, index=df1.index, columns=df2.index)

我建议两种可能的解决方案:

-使用scipys

-编写自己的numpy函数

scipy解决方案是直截了当的:

import scipy
import numpy as np

point_vector_1 = np.random.random((10000,2))
point_vector_2 = np.random.random((1000,2))
distance_matrix = scipy.spatial.distance_matrix(point_vector_1, point_vector_2)
在numpy中,我们可以使用外部ufunc来编写我们自己的函数。np.subtract.outer将作为两个向量的矩阵给出,类似于外点积给出的乘法

def euclidean_distance_matrix(vector_1, vector_2):
  dis_dim_1 = np.subtract.outer(vector_1.T[0], vector_2.T[0])**2
  dis_dim_2 = np.subtract.outer(vector_1.T[1], vector_2.T[1])**2
  euclidean = np.sqrt(dis_dim_1+dis_dim_2)
  return euclidean

distance_matrix_2 = euclidean_distance_matrix(point_vector_1, point_vector_2)
时间:

%timeit scipy.spatial.distance_matrix(point_vector_1, point_vector_2)
382 ms ± 8.56 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit euclidean_distance_matrix(point_vector_1, point_vector_2)
150 ms ± 1.33 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
编辑: 要保留原始索引,可以将源df的索引传递到新的数据帧:

dist_array = euclidean_distance_matrix([df1['lat'], df1['long']], [df2['lat'], df2['long']])
df_dist = pd.DataFrame(dist_array, index=df1.index, columns=df2.index)

你能提供测试数据吗?你的意思是:我的数据帧的第一个fue行吗?是的,你想归档的数据将在一分钟内添加。“存档”是什么意思?注意,
.apply
通常不会比
iterrows
快。您能提供测试数据吗?您的意思是:我的数据帧的第一行吗?是的,您想要存档的数据将在一分钟内添加。“归档”是什么意思?请注意,
.apply
通常不会比
iterrows
快。谢谢您的建议。这是一个很好的解决办法。请注意,编写自己的func会丢失数据帧的索引和标签,因此我无法判断新矩阵中的哪个向量是原始向量中的哪个列或行。有什么办法可以预防吗?谢谢你的建议。这是一个很好的解决办法。请注意,编写自己的func会丢失数据帧的索引和标签,因此我无法判断新矩阵中的哪个向量是原始向量中的哪个列或行。有什么办法可以预防吗?