这是一项数据清理练习,根据通过B解码的值,应该将dataframe的特定元素设置为NaN。
我编写了以下代码,其中3个嵌套循环将运行17h:
def Convert(input):
X = np.fromstring(input[1:-1], dtype=np.int, sep=',')
return X
tf = B
# B is a dataframe of descriptors for the A dataframe
# the column 'missing_or_unknown' in B is used to determine the elements of A to be replaced
tf['missing_or_unknown'] = B['missing_or_unknown'].apply(lambda x: Convert(x))
Y = tf['missing_or_unknown'].values
for i in range(0,len(A)):
for j in range(0,85):
for k in range (0,len(Y[j])):
if A.iloc[i,j] == Y[j][k]:
A[i,j] = np.nan我怀疑瓶颈是长的外循环,因为len(A)是一百万。因此,这不是最好的使用Pandas的方法,我会选择:
for j in range(0,85):
for k in range (0,len(Y[j])):
if A.iloc[:,j] == Y[j][k]:
A.iloc[:,j] = np.nan但是,后者抛出了一个异常:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()2个问题:
我对性能瓶颈的看法是正确的&得益于vectorization
发布于 2020-05-05 18:40:36
如果您想用np.nan替换A的任何条目,等于Y在同一位置的条目,则可以使用:
A[A==Y]=np.nan这能解决你的问题吗?
您的第一段代码可以工作,但是非常慢。
第二段代码无法工作,因为if语句是将整个列(系列)A.iloc[:,j]与一个值进行比较,您可以按照建议使用.any()进行比较。
在这里,我将比较我的代码wrt的速度--您第一次尝试使用维度100x85的两个dataframe:
import time
A = pd.DataFrame(np.zeros([100,85]))
A.iloc[0,1] = 1
Y = pd.DataFrame(np.ones([100,85]))
start_time = time.time()
A[A==Y]=np.nan
print("--- %s seconds ---" % (time.time() - start_time))
--- 0.030421018600463867 seconds ---
start_time = time.time()
for i in range(0,len(A)):
for j in range(0,85):
for k in range (0,len(Y[j])):
if A.iloc[i,j] == Y[j][k]:
A[i,j] = np.nan
print("--- %s seconds ---" % (time.time() - start_time))
--- 17.413578748703003 seconds ---https://stackoverflow.com/questions/61620242
复制相似问题