Python Pandalar: Sütunun belirli bir değerle eşleşen satır dizini al


276

"BoolCol" sütununa sahip bir DataFrame verildiğinde, "BoolCol" == True değerlerinin bulunduğu DataFrame dizinlerini bulmak istiyoruz

Şu anda mükemmel şekilde çalışan bunu yapmak için yinelenen bir yol var:

for i in range(100,3000):
    if df.iloc[i]['BoolCol']== True:
         print i,df.iloc[i]['BoolCol']

Ama bu panda'nın doğru yolu değil. Biraz araştırmadan sonra şu anda bu kodu kullanıyorum:

df[df['BoolCol'] == True].index.tolist()

Bu bana bir dizin listesi verir, ancak yaparak onları kontrol, onlar eşleşmiyor:

df.iloc[i]['BoolCol']

Sonuç aslında Yanlış !!

Bunu yapmanın doğru Pandalar yolu hangisi olurdu?

Yanıtlar:


428

df.iloc[i]ithsatırını döndürür df. idizin etiketine başvurmaz, i0 tabanlı bir dizindir.

Bunun aksine, özellikindex sayısal satır dizinlerini değil, gerçek dizin etiketlerini döndürür :

df.index[df['BoolCol'] == True].tolist()

Veya eşdeğer olarak,

df.index[df['BoolCol']].tolist()

Satırın sayısal konumuna eşit olmayan, varsayılan olmayan bir dizine sahip bir DataFrame ile oynayarak farkı oldukça net bir şekilde görebilirsiniz:

df = pd.DataFrame({'BoolCol': [True, False, False, True, True]},
       index=[10,20,30,40,50])

In [53]: df
Out[53]: 
   BoolCol
10    True
20   False
30   False
40    True
50    True

[5 rows x 1 columns]

In [54]: df.index[df['BoolCol']].tolist()
Out[54]: [10, 40, 50]

Dizini kullanmak istiyorsanız ,

In [56]: idx = df.index[df['BoolCol']]

In [57]: idx
Out[57]: Int64Index([10, 40, 50], dtype='int64')

o zaman kullanarak satırlarını seçebilir locyerineiloc :

In [58]: df.loc[idx]
Out[58]: 
   BoolCol
10    True
40    True
50    True

[3 rows x 1 columns]

locBoole dizilerini de kabul edebileceğinizi unutmayın :

In [55]: df.loc[df['BoolCol']]
Out[55]: 
   BoolCol
10    True
40    True
50    True

[3 rows x 1 columns]

Bir boolean diziniz varsa maskve sıralı dizin değerlerine ihtiyacınız varsa, bunları kullanarak bunları hesaplayabilirsiniznp.flatnonzero :

In [110]: np.flatnonzero(df['BoolCol'])
Out[112]: array([0, 3, 4])

df.ilocSıra dizinine göre satır seçmek için kullanın :

In [113]: df.iloc[np.flatnonzero(df['BoolCol'])]
Out[113]: 
   BoolCol
10    True
40    True
50    True

9
Yine başka bir yol yapmaktır df.query('BoolCol').
Phillip Cloud

3
Bu eski olduğunu biliyorum, ama bir sorgu 0 tabanlı dizin numaraları almak için kolay bir yolu olup olmadığını merak ediyorum. Belirli bir koşulu karşılayan bir satır önce ve sonra bazı satırları seçmek istiyorum çünkü iloc numaralarına ihtiyacım var. Bu yüzden planım koşulu karşılayan satırların 0-indekslerini almak ve iloc () 'de kullanmak için dilimler oluşturmaktı. Gördüğüm tek şey get_loc, ancak dizi alamaz.
sheridp

3
@sheridp: Bir boole maskesi varsa, nereye sıra indeksleri bulabilirsiniz maskolduğu Truekullanarak np.flatnonzero. Ne demek istediğimi göstermek için yukarıdaki yazıyı düzenledim.
unutbu

8
Öneriniz indices = np.flatnonzero(df[col_name] == category_name)bana tam olarak sorunun başlığı ne istiyor, bu internette bulmak şaşırtıcı derecede zor.
ClimbsRocks

Yalnızca dizini geri istiyorsanız, df [dftest] .index'in ek yükü nedir? Bu bir ara veri çerçevesi oluşturur mu (verileri gibabayt olabilir). Dftest ne olacak? Bu, döndürülen dizinin çok küçük veya hatta boş olabileceği çok büyük bir ara nesne de ayırmaz. Bunlar tembel görünümler kullanarak büyülü bir şekilde optimize edildi. Değilse, kesinlikle etkili bir yol olmalı.
user48956

31

Numpy where () işlevi kullanılarak yapılabilir:

import pandas as pd
import numpy as np

In [716]: df = pd.DataFrame({"gene_name": ['SLC45A1', 'NECAP2', 'CLIC4', 'ADC', 'AGBL4'] , "BoolCol": [False, True, False, True, True] },
       index=list("abcde"))

In [717]: df
Out[717]: 
  BoolCol gene_name
a   False   SLC45A1
b    True    NECAP2
c   False     CLIC4
d    True       ADC
e    True     AGBL4

In [718]: np.where(df["BoolCol"] == True)
Out[718]: (array([1, 3, 4]),)

In [719]: select_indices = list(np.where(df["BoolCol"] == True)[0])

In [720]: df.iloc[select_indices]
Out[720]: 
  BoolCol gene_name
b    True    NECAP2
d    True       ADC
e    True     AGBL4

Bir maç için her zaman dizine ihtiyacınız olmasa da, gerekirse ihtiyacınız varsa:

In [796]: df.iloc[select_indices].index
Out[796]: Index([u'b', u'd', u'e'], dtype='object')

In [797]: df.iloc[select_indices].index.tolist()
Out[797]: ['b', 'd', 'e']

2

Basit bir yol, filtrelemeden önce DataFrame dizinini sıfırlamaktır:

df_reset = df.reset_index()
df_reset[df_reset['BoolCol']].index.tolist()

Biraz kibirli, ama çabuk!


1

İlk queryolarak hedef sütunun ne zaman yazıldığını kontrol edebilirsiniz bool (PS: nasıl kullanılacağı hakkında lütfen bağlantıyı kontrol edin )

df.query('BoolCol')
Out[123]: 
    BoolCol
10     True
40     True
50     True

Orijinal df'yi Boole sütununa göre filtreledikten sonra dizini seçebiliriz.

df=df.query('BoolCol')
df.index
Out[125]: Int64Index([10, 40, 50], dtype='int64')

Ayrıca pandalar var nonzero, biz sadece seçmek pozisyonunu ait Truesatır ve kullanma o dilim DataFrameveyaindex

df.index[df.BoolCol.nonzero()[0]]
Out[128]: Int64Index([10, 40, 50], dtype='int64')

1

Dataframe nesnenizi yalnızca bir kez kullanmak istiyorsanız, şunu kullanın:

df['BoolCol'].loc[lambda x: x==True].index

0

Ben row, columnve valuetüm maçlar değerini nasıl bu soruyu uzattım ?

İşte çözüm:

import pandas as pd
import numpy as np


def search_coordinate(df_data: pd.DataFrame, search_set: set) -> list:
    nda_values = df_data.values
    tuple_index = np.where(np.isin(nda_values, [e for e in search_set]))
    return [(row, col, nda_values[row][col]) for row, col in zip(tuple_index[0], tuple_index[1])]


if __name__ == '__main__':
    test_datas = [['cat', 'dog', ''],
                  ['goldfish', '', 'kitten'],
                  ['Puppy', 'hamster', 'mouse']
                  ]
    df_data = pd.DataFrame(test_datas)
    print(df_data)
    result_list = search_coordinate(df_data, {'dog', 'Puppy'})
    print(f"\n\n{'row':<4} {'col':<4} {'name':>10}")
    [print(f"{row:<4} {col:<4} {name:>10}") for row, col, name in result_list]

Çıktı:

          0        1       2
0       cat      dog        
1  goldfish           kitten
2     Puppy  hamster   mouse


row  col        name
0    1           dog
2    0         Puppy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.