0

これは、データ フレーム A の特定の要素を、B を介してデコードされた値に応じて NaN に設定する必要があるデータ クリーニングの演習です。

3 ネストされたループが 17 時間実行される次のコードを作成しました。

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

ボトルネックは長い外部ループであると思われます.100len(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 つの質問:

  1. パフォーマンスのボトルネックとベクトル化のメリットについて、私の理解は正しいでしょうか?
  2. if条件を正しい方法で表現する方法
  3. Y の計算は高価ではありません。A データフレームの操作方法を決定するためのルックアップ配列です。
4

1 に答える 1

1

np.nan同じ位置にある Y のエントリに等しい A のエントリで置き換えたい場合は、次を使用できます。

A[A==Y]=np.nan

これで問題は解決しますか?

最初のコードは機能しますが、非常に遅いです。

if ステートメントが列全体 ( Series )A.iloc[:,j]を値と比較しているため、2 番目のコードは機能しません.any()

ここで、サイズが 100x85 の 2 つのデータフレームでの最初の試行と、私のコードの速度を比較します。

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 ---
于 2020-05-05T18:40:36.283 に答える