我正在分析和总结一个数据集(“theReport”),作为一个Python数据框架。该表显示了4个不同数据集(“输入”应在同一个键上匹配)之间的匹配过程的结果。你知道吗
在报告中,每个输入都有一个字段,其计数器与基本数据集的匹配数(>;=0)。我想更新报表中的一个字段,以指示有多少数据集与基础数据匹配(“matchCounter”),因此对于任何数量的成功匹配(即>;0),matchCounter应该以1递增,最多4个(即所有四个数据集都与基础数据匹配)。你知道吗
我在Jupyter笔记本中开发了这个过程,这个过程是在一个大约10万条记录的小数据集上进行的,虽然我成功地更新了matchCounter字段,但我怀疑它花费的时间比应该的要长。完整的数据集是10000条记录,根据我的粗略计算,用我当前的代码(我认为这是一个非常简单的操作)完成这项工作需要8个多小时。你知道吗
我已经读了一些关于提高数据帧(Pandas DataFrame performance)性能的内容,但是由于我是按顺序迭代行,并且if语句是在行中的项上测试的,而不是在数据帧上测试的,所以我不知道这是否适用。你知道吗
下面是代码的摘要版本。第一个for循环是导致瓶颈的循环:
import numpy as np
import pandas as pd
df = pd.read_csv(fileIn, header=0)
df['match_count']= 0
df['exclude']= False
# This for loop takes 300+ seconds to execute 100'000 times
for index, row in df.iterrows():
matchCounter = 0
if row['in_deeds'] > 0:
matchCounter += 1
if row['in_valuation'] > 0:
matchCounter += 1
if row['in_property'] > 0:
matchCounter += 1
if row['in_sg'] > 0:
matchCounter += 1
df.loc[index,'match_count'] = matchCounter
# This for loop takes only 11.75 seconds
i=0
for index, row in df.iterrows():
if "EXCL" in row['stat_deeds'].upper():
i=i+1
df.loc[index,'exclude']=True
elif "EXCL" in row['stat_valuation'].upper():
i=i+1
df.loc[index,'exclude']=True
elif "EXCL" in row['stat_property'].upper():
i=i+1
df.loc[index,'exclude']=True
elif "EXCL" in row['stat_sg'].upper():
i=i+1
df.loc[index,'exclude']=True
df = df.query('exclude == False')
这是我第一次和熊猫一起工作,我也是Python的初学者,所以我想我犯了一个愚蠢的错误。但我也不确定我的期望是否是错误的,这只是我应该期望的表现。有更好的办法吗?即使有人能给我指出正确的方向,我也会很感激的!你知道吗
操作后更新注释:
下面还将通过获取匹配计数的累计和来提供每个点(每行)的匹配总数。你知道吗
一件一件地:
我们首先检查(每行)指定列中的值是否大于零。这将返回一个布尔值
True
或False
,我们将其转换为整数.astype(int)
然后我们对每一行的值求和
.sum(axis=1)
。这将返回一个列,其中每行上我们知道满足了多少条件(
>0
)。你知道吗最后,我们计算行之间的累积和,以获得(每行)匹配的总数。你知道吗
最后,我们在原始数据帧
df
中创建一个新列df['match_count']=
,并将结果分配给该列。你知道吗在过去的数据帧迭代中,我也遇到过类似的问题-^{} 乍一看似乎是正确的选择,因为它易于使用,但是它的方便是有代价的。这里的a helpful blog概述了pandas中的方法,以提高迭代效率。你知道吗
结果是-不要使用
iterrows
。一般来说,可以使用索引作为迭代器,然后使用df.loc
或df.iloc
访问数据帧的行,如下所示:使用
df.apply
apply
方法允许您将用户定义的函数应用于数据帧的所有列或行。虽然这里的用法可能有些不直观,但它是迄今为止最快的:这里,函数将检查数据帧的每一行(由
axis=1
指定);np.any
返回True
如果布尔选择row[row > 0]
不是空的,此时布尔选择用np.sum
减少以获得最终计数。我们将raw
关键字参数设置为True
,以便传递原始的numpy
数组,该数组应用于减少操作(如sum)以提高性能(请参见docs)。你知道吗在我的机器上运行大约需要1.2秒。你知道吗
编辑
Gio的回答显示了一个原则,我认为这是使用pandas时的一个很好的实践——如果存在可以直接对数据帧进行操作的方法(例如
sum
,cumsum
),那么尝试使用这些方法,因为它们总是会更快。你知道吗在这样的方法不存在的地方,
df.apply
如果指定要应用的更复杂的操作,那么它会很有用-这只是未来的一个提示!你知道吗编辑II
上面带有apply的示例假设dataframe中的所有列都用于布尔选择。如果只有特定列具有需要用于计数器的数值,请在
counter
方法中使用Gio的建议:相关问题 更多 >
编程相关推荐