Panda veri çerçevesinde birden çok sütun seçme


1110

Farklı sütunlarda veri var ama başka bir değişkene kaydetmek için nasıl ayıklayacağımı bilmiyorum.

index  a   b   c
1      2   3   4
2      3   4   5

Nasıl seçerim 'a', 'b've df1 için kaydetmek?

denedim

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']

Hiçbiri işe yaramıyor.


2
.ixBelirsiz olduğu için asla kullanmak istemezsiniz . Gerekirse .ilocveya kullanın .loc.
Acumenus

1
Başlık adlarına başvurmadan yapılabilecek bir yol var mı? R'de olduğu gibi bunu şu şekilde yapabilirim: > csvtable_imp_1 <- csvtable_imp[0:6]ve 0 ile 6 arasında ilk sütunların delta miktarını seçer. Tek yapmam gereken csv-tablosunu readr lib ile ayrılmış olarak okumaktır.
MichaelR

Onunla biraz daha çalıştım. İstendiği gibi çalışan bir şey buldum. Varsayılan sütun sayısını değil karakter sayısını seçmektir. infile_1 = largefile_stay.ix[:,0:6]
MichaelR

3
Bu geç saatlerde tökezleyenler için ixartık kullanılmıyor. Pandalar şunlardan birini kullanmanızı önerir: loc(etiket tabanlı dizin oluşturma) veya iloc(konum tabanlı dizinleme).
ZaydH

Yanıtlar:


1768

Sütun adları (dize olan) denediğiniz şekilde dilimlenemez.

Burada birkaç seçeneğiniz var. Hangi değişkenleri dilimlemek istediğiniz bağlamdan biliyorsanız, __getitem__sözdizimine ([]) bir liste ileterek yalnızca bu sütunların bir görünümünü döndürebilirsiniz .

df1 = df[['a','b']]

Alternatif olarak, bunları adlarına göre değil sayısal olarak dizine eklemeniz önemliyse (kodunuzun ilk iki sütunun adını bilmeden bunu otomatik olarak yapması gerektiğini söyleyin), bunun yerine bunu yapabilirsiniz:

df1 = df.iloc[:,0:2] # Remember that Python does not slice inclusive of the ending index.

Ek olarak, bir Panda nesnesine bir görünüm fikri ve bu nesnenin bir kopyasıyla ilgili bilgi edinmelisiniz. Yukarıdaki yöntemlerden ilki, istenen alt nesnenin (istenen dilimler) belleğinde yeni bir kopya döndürür.

Bununla birlikte, bazen, Pandalar'da bunu yapmayan ve bunun yerine size orijinal nesnedeki alt nesne veya dilim ile aynı bellek yığınını ifade eden yeni bir değişken veren dizinleme kuralları vardır. Bu, dizine eklemenin ikinci yolu ile olur, böylece copy()düzenli bir kopya almak için işlevle değiştirebilirsiniz . Bu olduğunda, dilimlenmiş nesne olduğunu düşündüğünüz şeyi değiştirmek bazen orijinal nesneyi değiştirebilir. Bunun için her zaman iyi olmak.

df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df

Kullanmak ilociçin sütun konumlarını (veya dizinleri) bilmeniz gerekir. Sütun konumları değişebileceğinden, sabit kodlama indeksleri yerine, sütun indeksleri elde etmek için dataframe nesnesi yönteminin işleviyle ilocbirlikte kullanabilirsiniz .get_loccolumns

{df.columns.get_loc(c):c for idx, c in enumerate(df.columns)}

Artık bu sözlüğü kullanarak sütunlara adlar ve erişim yoluyla erişebilirsiniz iloc.


192
Not: df[['a','b']]bir kopyasını oluşturur
Wes McKinney

1
Evet, bu benim cevabımda örtükti. Kopya ile ilgili bit, yalnızca herhangi bir nedenle kullanmayı tercihix[] ederseniz kullanmak içindi . ix[]
ely

1
ixsütunları değil satırları indeksler. OP'nin sütunlar istediğini düşündüm.
ocaklar

9
ixdilim bağımsız değişkenlerini kabul eder, böylece sütunları da alabilirsiniz. Örneğin, df.ix[0:2, 0:2]sol üst 2x2 alt dizisini tıpkı bir NumPy matrisi için olduğu gibi alır (elbette sütun adlarınıza bağlı olarak). Sütunların dize adlarında da dilim sözdizimini kullanabilirsiniz df.ix[0, 'Col1':'Col5']. Bu , dizi arasında Col1ve dizide sipariş edilen tüm sütunları alır . Satırları endekslediğini söylemek yanlıştır . Bu sadece en temel kullanımıdır. Ayrıca bundan çok daha fazla endekslemeyi destekler. Yani, bu soru için mükemmel bir genel. Col5df.columnsixix
ely

7
@AndrewCassidy Bir daha asla .ix kullanmayın. Tamsayılarla dilimlemek istiyorsanız, .ilocPython listelerinde olduğu gibi son konumdan ayrı kullanın .
Ted Petrou

133

Sürümü 0.11.0 itibariyle sütunlar edilebilir kullandığınız çalıştı şekilde dilimlenmiş .locdizinleyiciyi:

df.loc[:, 'C':'E']

eşittir

df[['C', 'D', 'E']]  # or df.loc[:, ['C', 'D', 'E']]

ve Ciçinden sütunları döndürür E.


Rastgele oluşturulmuş bir DataFrame'de bir demo:

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 6)), 
                  columns=list('ABCDEF'), 
                  index=['R{}'.format(i) for i in range(100)])
df.head()

Out: 
     A   B   C   D   E   F
R0  99  78  61  16  73   8
R1  62  27  30  80   7  76
R2  15  53  80  27  44  77
R3  75  65  47  30  84  86
R4  18   9  41  62   1  82

Sütunları C'den E'ye almak için (tamsayı dilimlemenin aksine, sütunlarda 'E' bulunduğunu unutmayın):

df.loc[:, 'C':'E']

Out: 
      C   D   E
R0   61  16  73
R1   30  80   7
R2   80  27  44
R3   47  30  84
R4   41  62   1
R5    5  58   0
...

Etiketlere dayalı satırları seçmek için de aynı şey geçerlidir. Şu sütunlardan 'R6' ila 'R10' satırlarını alın:

df.loc['R6':'R10', 'C':'E']

Out: 
      C   D   E
R6   51  27  31
R7   83  19  18
R8   11  67  65
R9   78  27  29
R10   7  16  94

.locdizideki karşılık gelen girdisi olan sütunları seçebilmeniz için bir boole dizisini de kabul eder True. Örneğin , sütun adı listede yer alıyorsa - True değerini df.columns.isin(list('BCD'))döndürür ; Yanlış, aksi takdirde.array([False, True, True, True, False, False], dtype=bool)['B', 'C', 'D']

df.loc[:, df.columns.isin(list('BCD'))]

Out: 
      B   C   D
R0   78  61  16
R1   27  30  80
R2   53  80  27
R3   65  47  30
R4    9  41  62
R5   78   5  58
...

110

Sütun adlarınızın ( df.columns) olduğu varsayılarak, ['index','a','b','c']istediğiniz veriler 3. ve 4. sütunlardadır. Komut dosyanız çalıştığında adlarını bilmiyorsanız, bunu yapabilirsiniz

newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.

EMS cevabında belirttiği gibi , df.ixdilimler sütunları biraz daha kısaca, ancak .columnsvanilya 1-D piton listesi indeksleme / dilimleme sözdizimini kullandığından dilimleme arabirimi daha doğal olabilir.

UYARI: 'index'bir DataFramesütun için kötü bir addır . Aynı etiket aynı zamanda df.indexbir Indexdizi olan gerçek özellik için de kullanılır . Böylece sütununuz tarafından döndürülür df['index']ve gerçek DataFrame dizini tarafından döndürülür df.index. An Index, Seriesöğelerinin değerlerini aramak için optimize edilmiş özel bir türdür . Df.index için satırları etiketlerine göre aramak içindir. Bu df.columnsözellik aynı zamanda pd.Indexsütunları etiketlerine göre aramak için kullanılan bir dizidir.


3
Yukarıda benim yorumunda belirtildiği gibi, .ixolduğu değil sadece satırlar için. Genel amaçlı dilimleme içindir ve çok boyutlu dilimleme için kullanılabilir. Temelde sadece NumPy'nin olağan __getitem__sözdizimine bir arayüzdür . Bununla birlikte, sadece bir transpoze işlemi uygulayarak bir sütun dilimleme problemini bir satır dilimleme problemine kolayca dönüştürebilirsiniz df.T. Örneğin columns[1:3]biraz yanıltıcı olan örnek kullanır . Sonucu columnsbir Series; sadece bir dizi gibi davranmamaya dikkat edin. Ayrıca, muhtemelen columns[2:3]"3. ve 4." yorumunuzla eşleşecek şekilde değiştirmelisiniz .
ely

@ Mr.F: Benim [2:4]doğru. Sizin [2:3]yanlış. Ve bir dizi / Seri oluşturmak için standart python dilimleme gösterimini kullanmak IMO'yu yanıltmaz. Ancak, temel numpy dizisine erişmek için DataFrame arabirimini atlatmanızı seviyorum ix.
ocaklar

Bu durumda haklısın, ama yapmaya çalıştığım nokta, genel olarak, Pandalar'daki etiketlerle dilimlemenin dilim son noktasını kapsadığı (ya da en azından bu, önceki pandaların çoğundaki davranıştı). Eğer almak Yani eğer df.columnsve onu kesmek isteyecektir etikete göre , o zaman bunu dilim eğer farklı dilim anlambilim olurdu tamsayı endeksi pozisyonuna göre . Kesinlikle benim önceki yorum olsa iyi açıklanmadı.
ely

Ahh, şimdi anlıyorum. Bu columnsdeğişmez bir seri olduğunu unuttum ve alıcı etiketleri endeks olarak kullanmak için geçersiz kılındı. Açıklamak için zaman ayırdığınız için teşekkür ederiz.
ocaklar

2
Kullanım Dışı Bırakma Uyarısı: .ix kullanımdan kaldırılmıştır. Bu nedenle bu mantıklı: newdf = df [df.columns [2: 4]]
Martien Lubberink

64
In [39]: df
Out[39]: 
   index  a  b  c
0      1  2  3  4
1      2  3  4  5

In [40]: df1 = df[['b', 'c']]

In [41]: df1
Out[41]: 
   b  c
0  3  4
1  4  5

1
Ne gibi örneğin bir şey için, sütun adlandırmak istiyorsa: df[['b as foo', 'c as bar']çıktı sütunu yeniden adlandırır öyle ki bkadar foove sütunu colarak bar?
kuanb

5
df[['b', 'c']].rename(columns = {'b' : 'foo', 'c' : 'bar'})
Greg

61

Bu sorunun oldukça eski olduğunu biliyorum, ancak pandaların son sürümünde tam olarak bunu yapmanın kolay bir yolu var. (Dizeleri) Sütun adları olabilir ne gibi bir tarzda doğranır.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)

6
Bu sadece yaratımda yapılabilir. Soru, veri çerçevesine zaten sahip olup olmadığınızı sormaktır.
Banjocat

2
@ Banjocat, mevcut bir veri çerçevesi ile çalışır
mhery

23

Bırakılacak sütunların bir listesini sağlayabilir ve DataFrame'i yalnızca drop()bir Pandas DataFrame'deki işlevi kullanarak gereken sütunlarla geri döndürebilirsiniz.

Sadece söylüyorum

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)

Sadece sütunlu bir DataFrame dönecekti bve c.

dropYöntem belgelenmiştir burada .


23

Pandalarla,

zekâ sütun adları

dataframe[['column1','column2']]

iloc ve dizin numaralı belirli sütunlara göre seçmek için:

dataframe.iloc[:,[1,2]]

loc sütun isimleri ile gibi kullanılabilir

dataframe.loc[:,['column1','column2']]

20

Bu yöntemi çok yararlı buldum:

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]

Daha fazla ayrıntıyı burada bulabilirsiniz


Diyelim ki yalnızca 2. ve 5. sütunları nasıl alırdınız?
324

1
O zaman olurdu surveys_df.iloc [:, [2,5]].
Julian Gorfer

15

0.21.0 ile başlayarak, bir veya daha fazla eksik etikete sahip bir liste .locveya []listenin kullanılması tercih edilmez .reindex. Yani, sorunuzun cevabı:

df1 = df.reindex(columns=['b','c'])

Önceki sürümlerde, .loc[list-of-labels]anahtarlardan en az biri bulunduğu sürece kullanmak işe yarardı (aksi takdirde a değerini yükseltir KeyError). Bu davranış kaldırılmıştır ve şimdi bir uyarı iletisi gösterir. Önerilen alternatif.reindex() .

Verileri Dizinleme ve Seçme hakkında daha fazla bilgi edinin


10

Pandaları kullanabilirsiniz. DataFrame oluşturuyorum:

    import pandas as pd
    df = pd.DataFrame([[1, 2,5], [5,4, 5], [7,7, 8], [7,6,9]], 
                      index=['Jane', 'Peter','Alex','Ann'],
                      columns=['Test_1', 'Test_2', 'Test_3'])

DataFrame:

           Test_1  Test_2  Test_3
    Jane        1       2       5
    Peter       5       4       5
    Alex        7       7       8
    Ann         7       6       9

Ada göre 1 veya daha fazla sütun seçmek için:

    df[['Test_1','Test_3']]

           Test_1  Test_3
    Jane        1       5
    Peter       5       5
    Alex        7       8
    Ann         7       9

Ayrıca kullanabilirsiniz:

    df.Test_2

Ve sen sütun al Test_2

    Jane     2
    Peter    4
    Alex     7
    Ann      6

Düğmesini kullanarak bu satırlardan sütun ve satır da seçebilirsiniz .loc(). Buna "dilimleme" denir . Ben sütundan almak Bildirimi Test_1içinTest_3

    df.loc[:,'Test_1':'Test_3']

"Dilim":

            Test_1  Test_2  Test_3
     Jane        1       2       5
     Peter       5       4       5
     Alex        7       7       8
     Ann         7       6       9

Ve eğer sadece Peterve Annkolonlardan Test_1ve Test_3:

    df.loc[['Peter', 'Ann'],['Test_1','Test_3']]

Şunları elde edersiniz:

           Test_1  Test_3
    Peter       5       5
    Ann         7       9

8

Satır dizini ve sütun adına göre bir öğe almak istiyorsanız, bunu df['b'][0] . Görüntüleyebildiğiniz kadar basit.

Veya kullanabilirsiniz df.ix[0,'b'] indeks ve etiketin karışık kullanımını .

Not: v0.20 ix, loc/ lehine kullanımdan kaldırıldığından iloc.


6

Farklı ve kolay bir yaklaşım: yineleme satırları

iterows kullanarak

 df1= pd.DataFrame() #creating an empty dataframe
 for index,i in df.iterrows():
    df1.loc[index,'A']=df.loc[index,'A']
    df1.loc[index,'B']=df.loc[index,'B']
    df1.head()

5
Lütfen kaşıntı () kullanılmasını önermeyin. Pandalar tarihinin en kötü anti-paterninin açık bir sağlayıcısıdır.
cs95

"En kötü anti-desen" ile ne demek istediğinizi açıklar mısınız?
Ankita

1
Pandalar kullanılırken IMHO, iterrows () son seçenek olmalıdır.
Elf

5

Yukarıdaki yanıtlarda tartışılan farklı yaklaşımlar, kullanıcının sütun indekslerini bırakacağını veya alt kümeye ayarlayacağını bildiği veya kullanıcının bir sütun aralığı kullanarak bir veri çerçevesini alt kümeye ayırmak istediği varsayımına dayanmaktadır (örneğin, 'C': 'E' arasında) . pandas.DataFrame.drop () , kesinlikle kullanıcı tarafından tanımlanan sütun listesine dayanarak verileri alt kümeleştirmek için bir seçenektir (yine de her zaman dataframe'in kopyasını kullandığınıza dikkat etmelisiniz ve inplace parametreleri True olarak ayarlanmamalıdır. !!)

Başka bir seçenek de , sütun adlarında belirli bir fark yaratan ve istenen sütunları içeren bir dizi dizin türü döndüren pandas.columns.difference () yöntemini kullanmaktır . Çözüm aşağıdadır:

df = pd.DataFrame([[2,3,4],[3,4,5]],columns=['a','b','c'],index=[1,2])
columns_for_differencing = ['a']
df1 = df.copy()[df.columns.difference(columns_for_differencing)]
print(df1)

Çıktı: b c 1 3 4 2 4 5


1
Copy () gerekli değildir. ie: df1 = df[df.columns.difference(columns_for_differencing)]yeni / kopyalanmış bir veri çerçevesi döndürür. Değişiklik df1yapmadan değişiklik yapabilirsiniz df. Teşekkürler, btw. Tam da ihtiyacım olan buydu.
Bazyli Debowski

4

ayrıca df.pop () kullanabilirsiniz

>>> df = pd.DataFrame([('falcon', 'bird',    389.0),
...                    ('parrot', 'bird',     24.0),
...                    ('lion',   'mammal',   80.5),
...                    ('monkey', 'mammal', np.nan)],
...                   columns=('name', 'class', 'max_speed'))
>>> df
     name   class  max_speed
0  falcon    bird      389.0
1  parrot    bird       24.0
2    lion  mammal       80.5
3  monkey  mammal 

>>> df.pop('class')
0      bird
1      bird
2    mammal
3    mammal
Name: class, dtype: object

>>> df
     name  max_speed
0  falcon      389.0
1  parrot       24.0
2    lion       80.5
3  monkey        NaN

bunun size yardımcı olup olmadığını bize bildirin, lütfen df.pop (c) kullanın


3

Bu konuda birkaç cevap gördüm, ama benim için belirsiz kaldı. Bu ilgili sütunları nasıl seçersiniz? Bunun cevabı, eğer onları bir listede topladıysanız, sadece listeyi kullanarak sütunlara başvurabilirsiniz.

Misal

print(extracted_features.shape)
print(extracted_features)

(63,)
['f000004' 'f000005' 'f000006' 'f000014' 'f000039' 'f000040' 'f000043'
 'f000047' 'f000048' 'f000049' 'f000050' 'f000051' 'f000052' 'f000053'
 'f000054' 'f000055' 'f000056' 'f000057' 'f000058' 'f000059' 'f000060'
 'f000061' 'f000062' 'f000063' 'f000064' 'f000065' 'f000066' 'f000067'
 'f000068' 'f000069' 'f000070' 'f000071' 'f000072' 'f000073' 'f000074'
 'f000075' 'f000076' 'f000077' 'f000078' 'f000079' 'f000080' 'f000081'
 'f000082' 'f000083' 'f000084' 'f000085' 'f000086' 'f000087' 'f000088'
 'f000089' 'f000090' 'f000091' 'f000092' 'f000093' 'f000094' 'f000095'
 'f000096' 'f000097' 'f000098' 'f000099' 'f000100' 'f000101' 'f000103']

extracted_features63 sütun belirterek , aşağıdaki liste / numpy dizi var . Orijinal veri kümesinin 103 sütunu vardır ve tam olarak bunları ayıklamak istiyorum, o zaman

dataset[extracted_features]

Ve bununla sonuçlanacaksın

resim açıklamasını buraya girin

Bu, Makine Öğreniminde (özellikle özellik seçiminde) oldukça sık kullanacağınız bir şeydir. Ben de başka yolları tartışmak istiyorum, ama bunun zaten diğer istifleme makineleri tarafından karşılandığını düşünüyorum. Umarım bu yardımcı olmuştur!


2

Aşağıdaki pandas.DataFrame.filtergibi sütunları filtrelemek veya yeniden sıralamak için yöntemi kullanabilirsiniz :

df1 = df.filter(['a', 'b'])

0
df[['a','b']] # select all rows of 'a' and 'b'column 
df.loc[0:10, ['a','b']] # index 0 to 10 select column 'a' and 'b'
df.loc[0:10, ['a':'b']] # index 0 to 10 select column 'a' to 'b'
df.iloc[0:10, 3:5] # index 0 to 10 and column 3 to 5
df.iloc[3, 3:5] # index 3 of column 3 to 5
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.