簡體   English   中英

如何有效地從具有許多列的 Vaex DataFrame 中刪除非有限值?

[英]How can I efficiently remove non-finite values from a Vaex DataFrame with many columns?

我的數據具有等於正無窮大和負無窮大的值。 Vaex 具有dropnadropmissingdropnan的功能,但不能用於刪除非有限值。

我當前的方法是遍歷每個感興趣的列並覆蓋從每個列中刪除非有限值的過濾數據集:

...
for col in cols:
   df = df[df.col.isfinite()]
...

雖然這種方法確實給了我正確的結果,但它似乎非常低效,因為它需要很長時間才能運行,即使我的數據集只有幾行和幾千列也是如此。

在 Vaex 中刪除具有非有限值的行的首選方法是什么?

更新:

這是一個工作示例,用於演示我在一個微不足道的數據集上遇到的緩慢情況:

import vaex
import numpy as np
import pandas as pd

#create a dummy data frame with 1000 columns and a few rows, some with nan/inf
arr= []
for i in range(1000):
    arr.append([1] * 1 + [2] * 1 + [3] * 1 + [0] * 1 + [np.inf] * 1 + [-np.inf] * 1 + [np.nan] * 1)
df = pd.DataFrame(arr)
df = df.transpose()
df.columns = df.columns.map(str)
df = df.add_prefix('a')

df = vaex.from_pandas(df)

#eliminate rows that are not finite
for col in df.columns.keys(): #<-- this loop takes several minutes to run, I would expect it to be nearly instantaneous
    df = df[df[col].isfinite()]
df

更新 2 :單元格中的值略有不同,另一種選擇有限記錄的方法可以快速運行但返回不正確的結果:

import vaex
import numpy as np
import pandas as pd

arr= []
for i in range(2):
    if i == 1:
        arr.append([np.inf] * 1 + [2] * 1 + [3] * 1 + [0] * 1 + [1] * 1 + [1] * 1 + [1] * 1)
    else:
        arr.append([1] * 1 + [2] * 1 + [3] * 1 + [0] * 1 + [np.inf] * 1 + [-np.inf] * 1 + [np.nan] * 1)
df = pd.DataFrame(arr)
df = df.transpose()
df.columns = df.columns.map(str)
df = df.add_prefix('a')

df = vaex.from_pandas(df)
df
#   a0  a1
0   1   inf
1   2   2
2   3   3
3   0   0
4   inf 1
5   -inf    1
6   nan 1
is_col_finite = np.array([df[col].isfinite() for col in df.columns.keys()])
all_finite = np.all(is_col_finite, axis=0)
df = df[all_finite]
df
#   a0  a1
0   2   2
1   3   3
2   0   0
3   inf 1
4   -inf    1
5   nan 1

如果我很了解你的問題,你想刪除至少包含 1 個非有限值的行。

您可以創建一個to_keep變量,而不是在 for 循環的每次迭代中過濾df ,這將是一個 boolean 掩碼:

  • True == 保留該行
  • False == 刪除該行
to_keep = None
for column in df.columns:
   if to_keep is None:
      to_keep = df[column].isfinite()
   else:
      to_keep = to_keep and to_keep

df = df[to_keep]

我用你提供的片段試過這個:

import vaex
import numpy as np
import pandas as pd

arr = []
for i in range(1000):
    arr.append([1] * 1 + [2] * 1 + [3] * 1 + [0] * 1 + [np.inf] * 1 + [-np.inf] * 1 + [np.nan] * 1)
df = pd.DataFrame(arr)
df = df.transpose()
df.columns = df.columns.map(str)
df = df.add_prefix('a')

df = vaex.from_pandas(df)
  1. 在 for 循環的每次迭代中過濾:> 10 分鍾(我在結束前將其殺死,因為它花費了太多時間)
  2. 使用to_keep功能:3s

mask 的概念與您的UPDATE 2非常相似,其優點是只有一個向量而不是所有向量然后使用np.all

如果您想使用您的解決方案,您必須執行以下操作:

is_col_finite = np.array([df[col].isfinite().values for col in df.columns.keys()]) # add .values to convert the vaex expression to a numpy array
to_keep = np.all(is_col_finite, axis=0)

df["to_keep"] = to_keep
df[df["to_keep"]]

這將打印預期的 output:

a0  a1  to_keep
2   2   True
3   3   True
0   0   True 

備注:我不知道為什么但我不能直接使用df[to_keep]所以我不得不添加一個帶有掩碼的列


這是我的 vaex 包的版本:

vaex==3.0.0
vaex-arrow==0.5.1
vaex-astro==0.7.0
vaex-core==2.0.3
vaex-hdf5==0.6.0
vaex-jupyter==0.5.2
vaex-ml==0.9.0
vaex-server==0.3.1
vaex-viz==0.4.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM