Pandas Dataframe / Numpy Array "eksen" tanımında belirsizlik


92

Python eksenlerinin nasıl tanımlandığı ve bir DataFrame'in satırlarına veya sütunlarına atıfta bulunup bulunmadıkları konusunda kafam çok karıştı. Aşağıdaki kodu göz önünde bulundurun:

>>> df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], columns=["col1", "col2", "col3", "col4"])
>>> df
   col1  col2  col3  col4
0     1     1     1     1
1     2     2     2     2
2     3     3     3     3

Yani df.mean(axis=1)ararsak, satırlar arasında bir ortalama alacağız:

>>> df.mean(axis=1)
0    1
1    2
2    3

Ancak, çağırırsak df.drop(name, axis=1), aslında bir satır değil, bir sütun bırakırız:

>>> df.drop("col4", axis=1)
   col1  col2  col3
0     1     1     1
1     2     2     2
2     3     3     3

Birisi pandalarda / numpy / scipy'de "eksen" ile ne anlama geldiğini anlamama yardım edebilir mi?

Bir yan not, DataFrame.meanyanlış tanımlanmış olabilir. İçin bu belgelerde diyor DataFrame.meano axis=1sütunlar değil, satırlar üzerinde ortalama demek şimdi ...


Diğer adlar, 'sütunlar' ve 'dizin' / 'satırlar' hakkında ayrıntılı açıklama için aşağıdaki yanıta bakın .
Ted Petrou

Bu çok tuhaf. Eksen, meanve arasında tutarlı olmalıdır drop. Gerçek davranışa ulaşmak doğrusal olmayan düşünme gerektirir.
StephenBoesch

Yanıtlar:


168

Bunu 0 = aşağı ve 1 = çapraz olarak hatırlamak belki de en basitidir .

Bunun anlamı:

  • axis=0Her sütuna veya satır etiketlerine (dizin) bir yöntem uygulamak için kullanın .
  • axis=1Her satıra veya sütun etiketlerine bir yöntem uygulamak için kullanın .

Aşağıda, her eksenin başvurduğu bir DataFrame bölümlerini gösteren bir resim bulunmaktadır:

Pandas'ın NumPy'nin bu sözcüğü kullanışını izlediğini hatırlamakta fayda var axis. Kullanım, NumPy'nin terimler sözlüğünde açıklanmıştır :

Birden fazla boyuta sahip diziler için eksenler tanımlanır. 2 boyutlu bir dizinin iki karşılık gelen ekseni vardır: birincisi , satırlar boyunca dikey olarak aşağı doğru hareket eder (eksen 0) ve ikincisi , sütunlar boyunca yatay olarak çalışır (eksen 1) . [ vurgu ]

Dolayısıyla, sorudaki yöntemle ilgili df.mean(axis=1)olarak doğru tanımlanmış görünüyor. Girişlerin ortalamasını sütunlar boyunca , yani her bir satır boyunca yatay olarak alır . Öte yandan, sıralar boyuncadf.mean(axis=0) dikey olarak aşağı doğru hareket eden bir işlem olacaktır .

Benzer şekilde, df.drop(name, axis=1)sezgisel olarak yatay eksen boyunca ilerledikleri için sütun etiketleri üzerindeki bir eyleme atıfta bulunur. Belirtmek axis=0, yöntemin bunun yerine satırlar üzerinde çalışmasını sağlar.


3
Beni zorlayan şey, df.apply'nin (..., axis = 0), eksen 0 (dizin) "üzerinden geçmemesi", ancak sütunların üzerinden geçerek tüm dizinleri içeren Seriler döndürmesiydi. Buradaki ipucu, df.apply (..., axis = 0) 'ın Series'i döndürmesidir, böylece tüm indeks üzerinde çalışan bir işlemi uygulayabilirsiniz.
moritzschaefer

2
df.applyGibi bir yönteme benzer olarak görmenizin de yardımcı olacağını düşünüyorum df.sum. Örneğin df.sum(axis=0), DataFrame'in her sütununu toplar. Benzer şekilde, df.apply(sum, axis=0)tamamen aynı işlemi yapmak için yazabilirsiniz . İşlem gerçekten de DataFrame'deki her bir sütuna uygulanırken, gerçek işlev 0 ekseninden aşağı doğru çalışır.
Alex Riley

Bu adlandırma ve sipariş sözleşmeler talihsiz ters R 's fonksiyonu uygulamak R, düşük - MARGIN(benzer axisuygulandığı işlevi anlamına gelir "satır" den "1" tekabül değeri pandalarıyla olarak) her satır için , süre "2" nin daha büyük değeri, işlevin her sütuna uygulandığı anlamına gelen "sütunlara" karşılık gelir .
Keith Hughitt

pandalarda yıkıcı bir böcek
Calculus

10

Açıklamanın başka bir yolu:

// Not realistic but ideal for understanding the axis parameter 
df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]],
                  columns=["idx1", "idx2", "idx3", "idx4"],
                  index=["idx1", "idx2", "idx3"]
                 )

---------------------------------------1
|          idx1  idx2  idx3  idx4
|    idx1     1     1     1     1
|    idx2     2     2     2     2
|    idx3     3     3     3     3
0

Hakkında df.drop(eksen, konum anlamına gelir)

A: I wanna remove idx3.
B: **Which one**? // typing while waiting response: df.drop("idx3",
A: The one which is on axis 1
B: OK then it is >> df.drop("idx3", axis=1)

// Result
---------------------------------------1
|          idx1  idx2     idx4
|    idx1     1     1     1
|    idx2     2     2     2
|    idx3     3     3     3
0

Hakkında df.apply(eksen, yön anlamına gelir)

A: I wanna apply sum.
B: Which direction? // typing while waiting response: df.apply(lambda x: x.sum(),
A: The one which is on *parallel to axis 0*
B: OK then it is >> df.apply(lambda x: x.sum(), axis=0)

// Result
idx1    6
idx2    6
idx3    6
idx4    6

Sizce 1. eksen ve 0. eksene paralel aynı anlama gelmiyor mu?
Nuance

9

Zaten doğru cevaplar var, ancak size> 2 boyutlu başka bir örnek veriyorum.

Parametre axis, eksenin değiştirileceği anlamına gelir .
Örneğin, boyut ile bir dataframe olduğunu düşünün AxBxC .

  • df.mean(axis=1)boyut ax 1 xc olan bir veri çerçevesi döndürür .
  • df.drop("col4", axis=1)ax (b-1) xc boyutuna sahip bir veri çerçevesi döndürür .

Burada axis=1ikinci eksen anlamına gelir b, yani bbu örneklerde değer değişecektir.


1
Bu cevap, benim için bu konuda gördüğüm herhangi bir görselleştirmeden daha sezgisel. Ancak xarray, çok boyutlu diziler için pandalardan daha iyidir.
alys

2

0/1 tamsayılarının yerine dize takma adlarının 'indeks' ve 'sütunlar' kullanılabileceği daha yaygın olarak bilinmelidir . Takma adlar çok daha açık ve hesaplamaların nasıl yapıldığını hatırlamama yardımcı oluyor. "Dizin" için başka bir takma ad "satırlar" dır .

Ne zaman axis='index' kullanılır, sonra hesaplamaları kafa karıştırıcı sütunlar, aşağı olur. Ancak, başka bir satırla aynı boyutta bir sonuç aldığını hatırlıyorum.

Ne hakkında konuştuğumu görmek için ekrana biraz veri alalım:

df = pd.DataFrame(np.random.rand(10, 4), columns=list('abcd'))
          a         b         c         d
0  0.990730  0.567822  0.318174  0.122410
1  0.144962  0.718574  0.580569  0.582278
2  0.477151  0.907692  0.186276  0.342724
3  0.561043  0.122771  0.206819  0.904330
4  0.427413  0.186807  0.870504  0.878632
5  0.795392  0.658958  0.666026  0.262191
6  0.831404  0.011082  0.299811  0.906880
7  0.749729  0.564900  0.181627  0.211961
8  0.528308  0.394107  0.734904  0.961356
9  0.120508  0.656848  0.055749  0.290897

Tüm sütunların ortalamasını almak istediğimizde axis='index', aşağıdakileri elde etmek için kullanırız :

df.mean(axis='index')
a    0.562664
b    0.478956
c    0.410046
d    0.546366
dtype: float64

Aynı sonucu şu şekilde elde eder:

df.mean() # default is axis=0
df.mean(axis=0)
df.mean(axis='rows')

Satırlarda soldan sağa bir işlem kullanmak için, axis = 'column' kullanın. DataFrame'ime ek bir sütun eklenebileceğini düşünerek bunu hatırlıyorum:

df.mean(axis='columns')
0    0.499784
1    0.506596
2    0.478461
3    0.448741
4    0.590839
5    0.595642
6    0.512294
7    0.427054
8    0.654669
9    0.281000
dtype: float64

Aynı sonucu şu şekilde elde eder:

df.mean(axis=1)

Ax = 0 / index / rows ile yeni bir satır ekle

Açıklamayı tamamlamak üzere ek satırlar veya sütunlar eklemek için bu sonuçları kullanalım. Bu nedenle, ax = 0 / index / rows kullanıldığında, bu, DataFrame'in yeni bir satırını almak gibidir. Bir satır ekleyelim:

df.append(df.mean(axis='rows'), ignore_index=True)

           a         b         c         d
0   0.990730  0.567822  0.318174  0.122410
1   0.144962  0.718574  0.580569  0.582278
2   0.477151  0.907692  0.186276  0.342724
3   0.561043  0.122771  0.206819  0.904330
4   0.427413  0.186807  0.870504  0.878632
5   0.795392  0.658958  0.666026  0.262191
6   0.831404  0.011082  0.299811  0.906880
7   0.749729  0.564900  0.181627  0.211961
8   0.528308  0.394107  0.734904  0.961356
9   0.120508  0.656848  0.055749  0.290897
10  0.562664  0.478956  0.410046  0.546366

Eksen = 1 / sütunlar ile yeni bir sütun ekleyin

Benzer şekilde, eksen = 1 / sütun olduğunda, kolayca kendi sütununa dönüştürülebilen veriler oluşturacaktır:

df.assign(e=df.mean(axis='columns'))

          a         b         c         d         e
0  0.990730  0.567822  0.318174  0.122410  0.499784
1  0.144962  0.718574  0.580569  0.582278  0.506596
2  0.477151  0.907692  0.186276  0.342724  0.478461
3  0.561043  0.122771  0.206819  0.904330  0.448741
4  0.427413  0.186807  0.870504  0.878632  0.590839
5  0.795392  0.658958  0.666026  0.262191  0.595642
6  0.831404  0.011082  0.299811  0.906880  0.512294
7  0.749729  0.564900  0.181627  0.211961  0.427054
8  0.528308  0.394107  0.734904  0.961356  0.654669
9  0.120508  0.656848  0.055749  0.290897  0.281000

Aşağıdaki özel değişkenlerle tüm takma adları görebileceğiniz anlaşılıyor:

df._AXIS_ALIASES
{'rows': 0}

df._AXIS_NUMBERS
{'columns': 1, 'index': 0}

df._AXIS_NAMES
{0: 'index', 1: 'columns'}

1

Eksen = 'satırlar' veya eksen = 0 olduğunda, satırlar yönünde yukarıdan aşağıya erişim öğeleri anlamına gelir. Eksen boyunca toplam uygulanıyorsa = 0, bize her sütunun toplamını verecektir.

Eksen = 'sütunlar' veya eksen = 1 olduğunda, bu, sütunların yönünde soldan sağa erişim öğeleri anlamına gelir. Eksen = 1 boyunca toplam uygularsanız, her satırın toplamını alacağız.

Hala kafa karıştırıcı! Ama yukarıdakiler benim için biraz daha kolay hale getiriyor.


0

Diğer tüm cevapları kafa karıştırıcı buluyorum. Ben şöyle düşünüyorum:

axis=0: sonucun şekli yataydır (bir satır)
axis=1: sonucun şekli dikeydir (bir sütun)

Yani

  • df.drop(name, axis=1): bir sütun bırakır
  • df.mean(axis=1): bir sütun hesaplar (sonuç yeni bir sütun olarak eklenebilir)
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.