Pandalarda veri çerçevesi sütun dilimleri nasıl alınır


264

CSV dosyasından bazı makine öğrenimi verileri yüklüyorum. İlk 2 sütun gözlemlerdir ve kalan sütunlar özelliklerdir.

Şu anda aşağıdakileri yapıyorum:

data = pandas.read_csv('mydata.csv')

hangi gibi bir şey verir:

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))

İki dataframes bu dataframe dilim istiyorum: Biri sütunları içeren ave bve bir sütun içeren c, dve e.

Gibi bir şey yazmak mümkün değil

observations = data[:'c']
features = data['c':]

En iyi yöntemin ne olduğundan emin değilim. İhtiyacım var pd.Panelmı?

Bu arada, veri çerçevesi dizinini oldukça tutarsız buluyorum: data['a']izin verilir, ancak data[0]değil. Öte yandan, data['a':]izin verilmez, ancak izin verilir data[0:]. Bunun pratik bir nedeni var mı? Sütunlar Int tarafından dizine eklenmişse bu gerçekten kafa karıştırıcıdır.data[0] != data[0:1]


3
Df [...] yaptığınızda DataFrame doğal olarak dikte benzeri bir nesnedir, ancak df[5:10]satır seçmek için bazı kolaylıklar eklenmiştir ( pandas.pydata.org/pandas-docs/stable/… )
Wes McKinney

1
Peki bu tutarsızlık, tasarım lehine kolaylık lehine nedir? Tamam, ama yeni başlayanlar için kesinlikle daha açık olmalı!
cpa

3
Destek rahatlığının tasarım düşüncesi, öğrenme eğrisini daha dik hale getirir. Keşke sadece tutarlı bir arayüz sunan başlangıç ​​için daha iyi belgeler olmasını diliyorum. Örneğin, sadece ix arayüzüne odaklanın.
Yu Shen

Yanıtlar:


243

2017 Cevap - pandalar 0.20: .ix kullanımdan kaldırıldı. .Loc kullanın

Dokümanlardaki kullanımdan kaldırmaya bakın

.lochem satırları hem de sütunları seçmek için etiket tabanlı dizine ekleme özelliğini kullanır. Etiketler dizinin veya sütunların değerleridir. İle dilimleme .locson öğeyi içerir.

Diyelim aşağıdaki sütunlu bir DataFrame var varsayalım:
foo, bar, quz, ant, cat, sat, dat.

# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat

.locPython listelerinin hem satır hem de sütunlar için yaptığı dilim gösterimini kabul eder. Dilim gösterimi olmakstart:stop:step

# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat

# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar

# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat

# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned

# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar

# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat

# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat

Satır ve sütunlara göre dilimleyebilirsiniz. Örneğin, etiketlerle 5 satır varsa v, w, x, y,z

# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
#    foo ant
# w
# x
# y

Eğer kullanımınız lambda satırı ile uygulanırsa, olduğu gibi: df['newcol'] = df.apply(lambda row: myfunc(row), axis=1) o zaman myfunc(row){... kullanabilirsiniz row['foo':'ant']. örneğin ( bu StackOverflow yanıtına göre ) içinde, myfuncbunlardan herhangi birinin sayısal olmayan olup olmadığını değerlendirebilirsiniz:row['foo':'ant'].apply(lambda x: isinstance(x, str)).any()
pashute

4
.ilocyerine şimdi kullanılmalıdır .loc. Bunu düzeltin, ben de oylayacağım.
craned

1
@craned - bu doğru değil. Panda'nın belgelerinden: .loc esas olarak etiket tabanlıdır, ancak bir boolean dizisiyle de kullanılabilir. .loc, öğeler bulunamadığında KeyError değerini yükseltir. Benzer bir ifade, özellikle indeks tabanlı dilimlemeyi ifade ettiği sürece .iloc hakkında yapılır. Başka bir deyişle, etiket tabanlı indeksleme kullandı ve .loc doğru seçimdir (temel olarak tek seçim). Örneğin -rows 5:10 konumuna göre dilimlemek istiyorsanız, .iloc
user2103050

149

Not: .ix Pandas v0.20'den bu yana kullanımdan kaldırılmıştır. Bunun yerine .locveya .ilocuygun şekilde kullanmalısınız .

DataFrame.ix dizini erişmek istediğiniz şeydir. Biraz kafa karıştırıcı (Pandalar dizine eklemenin zaman zaman şaşırtıcı olduğunu kabul ediyorum!), Ancak aşağıdakileri istediğiniz gibi yapıyor:

>>> df = DataFrame(np.random.rand(4,5), columns = list('abcde'))
>>> df.ix[:,'b':]
      b         c         d         e
0  0.418762  0.042369  0.869203  0.972314
1  0.991058  0.510228  0.594784  0.534366
2  0.407472  0.259811  0.396664  0.894202
3  0.726168  0.139531  0.324932  0.906575

burada .ix [satır dilimi, sütun dilimi] yorumlanan şeydir. Pandalar dizine ekleme hakkında daha fazla bilgi için: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced


5
Pandalardaki aralıkların her iki uç noktasını da içerdiğine dikkat edin, yani>>>data.ix[:, 'a':'c'] a b c 0 0.859192 0.881433 0.843624 1 0.744979 0.427986 0.177159
çekirge 13

21
Birden fazla sütun kabini bu şekilde aktarıldıdf.ix[:,[0,3,4]]
user602599

3
@Karmel: Yukarıdaki çıktıda bir kopyalama / yapıştırma hatası var gibi görünüyor. Belki demek istedin df.ix[:,'b':'e']?
ChaimG

6
Bunun locyerine kullanmak daha iyidir ix: stackoverflow.com/a/31593712/4323
John Zwinck

5
Bunun gibi eski yanıtların silinmesi gerekir. .ix kullanımdan kaldırılmıştır ve asla kullanılmamalıdır.
Ted Petrou

75

Örnek olarak deniz dibi paketinin titanik veri setini kullanalım

# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')

sütun adlarını kullanma

>> titanic.loc[:,['sex','age','fare']]

sütun indekslerini kullanma

>> titanic.iloc[:,[2,3,6]]

ix kullanarak (Pandalar <.20 sürümünden daha eski)

>> titanic.ix[:,[‘sex’,’age’,’fare’]]

veya

>> titanic.ix[:,[2,3,6]]

reindex yöntemini kullanarak

>> titanic.reindex(columns=['sex','age','fare'])

6
Pandalarda 0.20: .ixkullanımdan kaldırıldı.
Shihe Zhang

Kullanımdan kaldırma uyarısı: Passing list-likes to .loc or [] with any missing label will raise KeyError in the future, you can use .reindex() as an alternative.kullandığınızdadf.loc[:, some_list_of_columns]
Marc Maxmeister

35

Ayrıca, bir DataFrame verildi

veri

örneğinizde olduğu gibi, yalnızca a ve d sütunlarını (ei 1. ve 4. sütun) ayıklamak istiyorsanız, panda veri çerçevesinden iloc mothod ihtiyacınız olan şeydir ve çok etkili bir şekilde kullanılabilir. Bilmeniz gereken tek şey ayıklamak istediğiniz sütunların dizinidir. Örneğin:

>>> data.iloc[:,[0,3]]

sana vereceğim

          a         d
0  0.883283  0.100975
1  0.614313  0.221731
2  0.438963  0.224361
3  0.466078  0.703347
4  0.955285  0.114033
5  0.268443  0.416996
6  0.613241  0.327548
7  0.370784  0.359159
8  0.692708  0.659410
9  0.806624  0.875476

25

DataFrameBir listedeki her bir sütunun adlarına bakarak a'nın sütunları boyunca dilimleyebilirsiniz , şöyle:

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]

Eğer 'b' sütunundan başlayarak tüm verileri istiyorsam, data.columns içinde 'b' indeksini bulmam ve data [data.columns [1:]] yapmam gerekiyor mu? Çalışmanın kanonik yolu bu mu?
cpa

1
'B' den sonraki tüm sütunları seçmek mi istiyorsunuz?
Brendan Wood

Evet veya belirli bir aralıktaki tüm sütunları seçme.
cpa

Kendimi pandalar için oldukça yeniyim, bu yüzden kanonik kabul edilen şey hakkında konuşamam. Söylediğin gibi yapardım, ancak 'b' sütununun dizinini veya her neyse belirlemek için get_locişlevi kullanın data.columns.
Brendan Wood

20

Ve buraya iki sütun aralığını dilimlemek ve bunları birleştirmek (benim gibi) için geldiyseniz,

op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op

Bu, ilk 900 sütun ve (tümü) sütun> 3593 olan yeni bir veri çerçevesi oluşturur (veri kümenizde 4000 sütun olduğu varsayılır).


Harika, biri bunu denedi ... Merak ediyordum, ilk 900 sütunu alan bu 0: 899 .. neden böyle yaptılar? Bu hiç Python gibi hissetmiyor. Python aralıklarını kullanırken her zaman 'kadar' kadar 've dahil değildir'
zwep

14

Seçmeli etiket tabanlı, dizin tabanlı ve seçici aralık tabanlı sütun dilimleme dahil olmak üzere seçici sütun dilimleme yapmak için farklı yöntemleri nasıl kullanabileceğiniz aşağıda açıklanmıştır .

In [37]: import pandas as pd    
In [38]: import numpy as np
In [43]: df = pd.DataFrame(np.random.rand(4,7), columns = list('abcdefg'))

In [44]: df
Out[44]: 
          a         b         c         d         e         f         g
0  0.409038  0.745497  0.890767  0.945890  0.014655  0.458070  0.786633
1  0.570642  0.181552  0.794599  0.036340  0.907011  0.655237  0.735268
2  0.568440  0.501638  0.186635  0.441445  0.703312  0.187447  0.604305
3  0.679125  0.642817  0.697628  0.391686  0.698381  0.936899  0.101806

In [45]: df.loc[:, ["a", "b", "c"]] ## label based selective column slicing 
Out[45]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [46]: df.loc[:, "a":"c"] ## label based column ranges slicing 
Out[46]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [47]: df.iloc[:, 0:3] ## index based column ranges slicing 
Out[47]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

### with 2 different column ranges, index based slicing: 
In [49]: df[df.columns[0:1].tolist() + df.columns[1:3].tolist()]
Out[49]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

Lütfen kodu sadece yanıt olarak atmaktan kaçının ve ne yaptığını ve nedenini açıklamaya çalışın. Kodunuz, ilgili kodlama deneyimine sahip olmayan kişiler için açık olmayabilir. Lütfen cevabınızı açıklama, bağlam
Sᴀᴍ Onᴇᴌᴀ

1

Eşdeğeri

 >>> print(df2.loc[140:160,['Relevance','Title']])
 >>> print(df2.ix[140:160,[3,7]])

1

Veri çerçevesi şöyle görünürse:

group         name      count
fruit         apple     90
fruit         banana    150
fruit         orange    130
vegetable     broccoli  80
vegetable     kale      70
vegetable     lettuce   125

ve OUTPUT şöyle olabilir

   group    name  count
0  fruit   apple     90
1  fruit  banana    150
2  fruit  orange    130

mantıksal işleç kullanırsanız np.logical_not

df[np.logical_not(df['group'] == 'vegetable')]

hakkında daha ayrıntılı

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html

diğer mantıksal operatörler

  1. logical_and (x1, x2, / [, out, where, ...]) x1 AND x2 öğesinin doğruluk değerini hesaplayın.

  2. logical_or (x1, x2, / [, out, where, cast, ...]) x1 OR x2 element-wise'nin gerçek değerini hesaplayın.

  3. logical_not (x, / [, dışarı, nerede, döküm, ...]) NOT x element-wise'nin gerçek değerini hesaplayın.
  4. logical_xor (x1, x2, / [, out, where, ..]) x1 XOR x2 öğesinin doğruluk değerini element olarak hesaplayın.

0

Tüm satırları istediğinizi varsayarak, DataFrame'inizden bir sütun alt kümesi almanın başka bir yolu da şu olurdu:
data[['a','b']]ve data[['c','d','e']]
Sayısal sütun dizinlerini kullanmak istiyorsanız şunları yapabilirsiniz:
data[data.columns[:2]]vedata[data.columns[2:]]

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.