我有一个可以广泛使用excel文件(SAP下载)的代码(数据转换和计算步骤)。
我需要将所有行(几千行)循环几次。我之前写过一段代码,分别添加数据帧列,因此我可以在一个for循环中完成所有操作,当然这相当快,但是,我必须更改数据源,这意味着原始数据结构的更改。
原始数据结构的前3行为空,然后标题行带有列名,然后2行为空,第一列也为空。我决定删除这些,并分配列名并使其成为标题(以下步骤),但是,从那时起,单独添加列名并在一个for语句中计算所有内容并不会将数据填充到这些特定列中。
如何优化此代码
我删除了一些计算步骤,因为它们相当长,使代码部分的可读性更低
#This function adds new column to the dataframe
def NewColdfConverter(*args):
for i in args:
dfConverter[i] = '' #previously used dfConverter[i] = NaN
#This function creates dataframe from excel file
def DataFrameCreator(path,sheetname):
excelFile = pd.ExcelFile(path)
global readExcel
readExcel = pd.read_excel(excelFile,sheet_name=sheetname)
#calling my function to create dataframe
DataFrameCreator(filePath,sheetName)
dfConverter = pd.DataFrame(readExcel)
#dropping NA values from Orders column (right now called Unnamed)
dfConverter.dropna(subset=['Unnamed: 1'], inplace=True)
#dropping rows and deleting other unnecessary columns
dfConverter.drop(dfConverter.head(1).index, inplace=True)
dfConverter.drop(dfConverter.columns[[0,11,12,13,17,22,23,48]], axis = 1,inplace = True)
#renaming columns from Unnamed 1: etc to proper names
dfConverter = dfConverter.rename(columns={Unnamed 1:propername1 Unnamed 2:propername2 etc.})
#calling new column function -> this Day column appears in the 1st for loop
NewColdfConverter("Day")
#example for loop that worked prior, but not working since new dataset and new header/column steps added:
for i in range(len(dfConverter)):
#Day column-> floor Entry Date -1, if time is less than 5:00:00
if(dfConverter['Time'][i] <= time(hour=5,minute=0,second=0)):
dfConverter['Day'][i] = pd.to_datetime(dfConverter['Entry Date'][i])-timedelta(days=1)
else:
dfConverter['Day'][i] = pd.to_datetime(dfConverter['Entry Date'][i])
问题是,有许多列彼此构建,所以我无法在一个for循环中获取它们,例如,在下面的示例中,我需要计算reqsWoSetUpValue,这样我就可以计算requirementsValue,这样我就可以计算其他ReqsValue,但我无法通过将值分配给dataframecolumn[I]行在1 for循环中实现这一点,因为值将丢失,就像什么都没有发生一样。
(dfsorted与dfConverter相同,但它是一个排序版本)
#example code of getting reqsWoSetUpValue
for i in range(len(dfSorted)):
reqsWoSetUpValue[i] = #calculationsteps...
#inserting column with value
dfSorted.insert(49,'Reqs wo SetUp',reqsWoSetUpValue)
#getting requirements value with previously calculated Reqs wo SetUp column
for i in range(len(dfSorted)):
requirementsValue[i] = #calc
dfSorted.insert(50,'Requirements',requirementsValue)
#Calculating Other Reqs value with previously calculated Requirements column.
for i in range(len(dfSorted)):
otherReqsValue[i] = #calc
dfSorted.insert(51,'Other Reqs',otherReqsValue)
任何人都有一个线索,为什么我不能在1 for循环中通过首先通过函数添加所有列来实现这一点,比如:
NewColdfConverter('Reqs wo setup','Requirements','Other reqs')
#then in 1 for loop:
for i in range(len(dfsorted)):
dfSorted['Reqs wo setup'] = #calculationsteps
dfSorted['Requirements'] = #calculationsteps
dfSorted['Other reqs'] = #calculationsteps
多谢各位
不确定这是否会提高性能,但可以使用DataFrame.iterrows()同时逐行计算依赖列
一般性意见:如何识别瓶颈
要开始,您应该尝试识别代码的哪些部分比较慢
方法1:使用
time
包的时间代码部分将代码块包装在如下语句中:
方法2:使用探查器
Spyder有一个内置的探查器。这允许您检查哪些操作最耗时
矢量化您的操作
如果对操作进行向量化,代码的速度将提高几个数量级。看起来你的循环都是可以避免的
例如,与其对每一行分别调用
pd.to_datetime
,不如对整个列同时调用它如果要对行的子集执行操作,也可以使用
loc
在矢量化操作中执行此操作:相关问题 更多 >
编程相关推荐