2016-11-06 258 views
3

我想根據特定條件從DataFrame中選擇列。我知道它可以用循環完成,但我的df非常大,所以效率至關重要。列選擇的條件是隻有non-nan條目或只有nans的序列,後跟一個只有non-nan條目的序列。熊貓中的條件列選擇

下面是一個例子。請看下面的數據框:

pd.DataFrame([[1, np.nan, 2, np.nan], [2, np.nan, 5, np.nan], [4, 8, np.nan, 1], [3, 2, np.nan, 2], [3, 2, 5, np.nan]]) 

    0 1 2 3 
0 1 NaN 2.0 NaN 
1 2 NaN 5.0 NaN 
2 4 8.0 NaN 1.0 
3 3 2.0 NaN 2.0 
4 3 2.0 5.0 NaN 

從的話,我想只選擇列0和1。關於如何做到這一點沒有有效循環有什麼建議?

回答

2

邏輯

  • 計數每一列中的空值。如果唯一的空值在開頭,那麼列中空值的數量應該等於第一個有效索引的位置。
  • 獲取第一個有效索引
  • 按空計數對索引進行分片並與第一個有效索引進行比較。如果它們相等,那麼這就是一個很好的列

cnull = df.isnull().sum() 
fvald = df.apply(pd.Series.first_valid_index) 
cols = df.index[cnull] == fvald 
df.loc[:, cols] 

enter image description here


與速度提升

老答案

主編
def pir1(df): 
    cnull = df.isnull().sum() 
    fvald = df.apply(pd.Series.first_valid_index) 
    cols = df.index[cnull] == fvald 
    return df.loc[:, cols] 

使用快得多回答相同的邏輯

def pir2(df): 
    nulls = np.isnan(df.values) 
    null_count = nulls.sum(0) 
    first_valid = nulls.argmin(0) 
    null_on_top = null_count == first_valid 
    filtered_data = df.values[:, null_on_top] 
    filtered_columns = df.columns.values[null_on_top] 
    return pd.DataFrame(filtered_data, df.index, filtered_columns) 

enter image description here

+0

由於@piRSquared。這個解決方案確實完成了工作,但運行時間比下面發佈的解決方案長3倍以上 – splinter

+0

@splinter我並不感到驚訝。我想到尼基爾走的路線,但我選擇了簡潔。尼基提供了一個很好的答案。儘管使用相同的邏輯,我會更新我的文章,但利用一些技巧加快速度。 – piRSquared

+0

聽起來不錯@piRSquared – splinter

1

考慮一個DF所示,其具有以各種可能的位置Nans

Image

1.雙方Nans

通過用0和有限值與1的更換所有的NaN創建掩模:

mask = np.where(np.isnan(df), 0, 1) 

採取它橫跨每個對應的元素差柱。接下來,取其值。這裏的邏輯是,每當每列中有三個唯一值時,則丟棄該列(即→-1,1,0),因爲在這種情況下會有序列中斷。

想法是取總和並創建一個子集,只要總和結果小於2的值。(因爲在mod之後,我們得到1,1,0)。所以,對於極端情況,我們得到總和爲2,這些列當然是不相交的,必須丟棄。

criteria = pd.DataFrame(mask, columns=df.columns).diff(1).abs().sum().lt(2) 

最後轉置DF,並使用該條件,重新轉置來獲得具有另一個在一個僅Nans部和有限值所需的結果。

df.loc[:, criteria] 

Image

2. Nans存在於頂部:

mask = np.where(np.isnan(df), 0, 1) 
criteria = pd.DataFrame(mask, columns=df.columns).diff(1).ne(-1).any() 
df.loc[:, criteria] 

Image

+0

非常棒@NickiMaveli,它的速度比上面的解決方案快3倍。 – splinter