矢量化熊猫数据帧

时间:2020-05-05 18:22:22

标签: python pandas auto-vectorization

这是一个数据清理活动,其中应根据通过B解码的值将数据帧A的特定元素设置为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)约为100万。因此,这不是使用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个问题:

  1. 我对性能瓶颈是否正确,并从矢量化中受益
  2. 如何正确表达if条件
  3. Y的计算并不昂贵,它是一个查找数组,用于确定如何操纵A数据框

1 个答案:

答案 0 :(得分:1)

如果您要用np.nan替换在相同位置上等于A的Y的任何条目,则可以使用:

A[A==Y]=np.nan

这能解决您的问题吗?

您的第一个代码可以运行,但是非常慢。

您的第二个代码不起作用,因为if语句将整个列( Series A.iloc[:,j]与一个值进行比较,您可以使用.any()进行操作,例如建议。

在这里,我将比较您第一次尝试使用尺寸为100x85的两个数据框的代码的速度:

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 ---