2016-11-17 102 views
10

比方說,我有這樣一個獲取數據幀的第一行Python中的熊貓

import pandas as pd 
df = pd.DataFrame([[1, 2, 1], [1, 3, 2], [4, 6, 3], [4, 3, 4], [5, 4, 5]], columns=['A', 'B', 'C']) 

>> df 
    A B C 
0 1 2 1 
1 1 3 2 
2 4 6 3 
3 4 3 4 
4 5 4 5 

原來的表是有更多的列和行更復雜數據幀。

我想獲得滿足一些條件的第一行。實例:

  1. 獲取第一行,其中A> 3(返回行2)
  2. 獲取第一行,其中A> 4和B> 3(返回行4)
  3. 獲取第一行,其中A> 3 AND (B> 3或C> 2)(返回第2行)

但是,如果沒有滿足特定條件的任何行,那麼我想在得到第一個行之後, A(或B,C等其他情況)

  1. 獲取第一行,其中A> 6(由一個遞減排序,返回第4行,並獲得第一個)

我能夠通過迭代的數據幀做到這一點(我知道擲骰子:P)。所以,我更喜歡用pythonic來解決它。

+0

第一行> 4 4,你可以檢查你正在搜索試驗 – Boud

+0

[布爾索引(http://pandas.pydata.org /pandas-docs/stable/indexing.html#boolean-indexing)? – Kartik

+0

@Boud對不起。輸入錯誤:( – Tasos

回答

13

This tutorial是一個非常好的一個大熊貓切片。確保你檢查出來。在一些片斷......切帶條件的數據框,您使用這種格式:

>>> df[condition] 

這將返回您可以使用索引您iloc數據幀中分得一杯羹。這裏是你的例子:

  1. 獲取第一行,其中A> 3(返回行)

    >>> df[df.A > 3].iloc[0] 
    A 4 
    B 6 
    C 3 
    Name: 2, dtype: int64 
    

如果你真正想要的是行號,而不是使用iloc,它將是df[df.A > 3].index[0]

  • 獲取第一行,其中A> 4和B> 3:

    >>> df[(df.A > 4) & (df.B > 3)].iloc[0] 
    A 5 
    B 4 
    C 5 
    Name: 4, dtype: int64 
    
  • 獲取第一行,其中A> 3 AND(B> 3或C> 2 )(返回第2行)

    >>> df[(df.A > 3) & ((df.B > 3) | (df.C > 2))].iloc[0] 
    A 4 
    B 6 
    C 3 
    Name: 2, dtype: int64 
    
  • 現在,你最後的情況下,我們可以編寫處理返回下降排序幀的默認情況下的函數:

    >>> def series_or_default(X, condition, default_col, ascending=False): 
    ...  sliced = X[condition] 
    ...  if sliced.shape[0] == 0: 
    ...   return X.sort_values(default_col, ascending=ascending).iloc[0] 
    ...  return sliced.iloc[0] 
    >>> 
    >>> series_or_default(df, df.A > 6, 'A') 
    A 5 
    B 4 
    C 5 
    Name: 4, dtype: int64 
    

    正如預期的那樣,它會返回第4行

    7

    對於現有的匹配,使用query

    df.query(' A > 3').head(1) 
    Out[33]: 
        A B C 
    2 4 6 3 
    
    df.query(' A > 4 and B > 3').head(1) 
    Out[34]: 
        A B C 
    4 5 4 5 
    
    df.query(' A > 3 and (B > 3 or C > 2)').head(1) 
    Out[35]: 
        A B C 
    2 4 6 3 
    
    +0

    查詢看起來確實比我的切片方法更清潔。 – PabTorre

    1

    可以照顧到第3項和切片頭:

    1. df[df.A>=4].head(1)
    2. df[(df.A>=4)&(df.B>=3)].head(1)
    3. df[(df.A>=4)&((df.B>=3) * (df.C>=2))].head(1)

    的情況下,沒有任何條件回來,你可以用,如果嘗試或處理...

    try: 
        output = df[df.A>=6].head(1) 
        assert len(output) == 1 
    except: 
        output = df.sort_values('A',ascending=False).head(1)