Yerinde Anlamak = Doğru


104

Gelen pandaskütüphane defalarca şu ifadeye gibi INPLACE nesneyi değiştirmek için bir seçenek yoktur ...

df.dropna(axis='index', how='all', inplace=True)

Neyin iade edildiğini ve nesnenin ne zaman inplace=Trueve ne zaman geçildiğini nasıl ele aldığını merak ediyorum inplace=False.

Tüm işlemler selfne zaman değişiyor inplace=True? Ve inplace=Falsegibi yeni bir nesne ne zaman hemen oluşturulur new_df = selfve sonra new_dfdöndürülür?


13
Evet, inplace=Truedöner None inplace=Falseoperasyonla nesnenin döner bir kopyası gerçekleştirilir. Dokümanlar bu konuda oldukça açık, belirli bir bölümle karıştıran bir şey var mı? SpeficallyIf True, do operation inplace and return None.
EdChum

DataFrame nesnesinin alt sınıflarını oluşturuyorum ve birleştirme gibi bir işlemle bunu yerinde yapmak mümkün görünmüyor ... self = self.merge(new_df, how='left', on='column2' Kendini yeniden atamanın mümkün olduğundan emin değilim
Aran Freel

1
DataFrame.merge'ininplace argümanı olmadığı konusunda haklısınız . Bir DataFrame döndürür, bu nedenle yeniden atama sorunu yoktur.
JAV

Birisi kaynak tüketimi açısından kullanmanın avantajlarını da vurgulayabilir mi?
markroxor

2
@markroxor Gerçekten çok yok. Birkaç örnekte, inplacesonucun bir kopyasını döndürmeniz gerekmediğinden eylem biraz daha hızlı olabilir. Ama bununla ilgili. Kullanmamak için çok daha fazla neden var.
cs95

Yanıtlar:


96

Ne zaman inplace=Truegeçirilir Kullanmak istiyorum, böylece veri, yeri (hiçbir şey döndüren) 'de yeniden adlandırılır:

df.an_operation(inplace=True)

Ne zaman inplace=Falsegeçirilir (bu varsayılan değerdir, dolayısıyla gerekli değildir), işlemi gerçekleştirir ve nesnenin bir kopyasını döndürür, böylece şunu kullanacaksınız:

df = df.an_operation(inplace=False) 

Bunun inplaceyalnızca mevcut verileri değiştiren yöntemler için bir seçenek olduğunu, ancak verileri 'yeniden şekillendiren' yöntemler için olmadığını düşünmekte haklı mıyım ? Örneğin, mevcut dizine değerler uyguladığından .set_index (inplace = True) yapabilirim, ancak .reindex (inplace = True) yapamıyorum çünkü bu, DataFrame'de önceki dizide bulunmayan fazladan satırlar oluşturabilir ?
ac24

4
Yöntem veri çerçevesini .dropna()kabul eder inplace=Trueve kesinlikle yeniden şekillendirebilir, bu nedenle hayır.
jorijnsmit

3
Burada dikkatli olmalısın. @ ac24 aslında aşağı yukarı doğru. İken dropnagetiri farklı şekildeki bir dataframe, aslında temel verilerin yeniden şekillendirmek değil - bu sadece üzerinde bir maske (döndüren inplace=Falsekorkunç yol açabilir), SettingWithCopyWarning. Yalnızca eski değerler dizisine daha fazla başvuru olmadığında pandalar maskeye göre yeniden şekillenir. Daha iyi bir genel kural şudur: inplaceişlem, yeni bir değer dizisi tahsis etmeyi gerektirmediğinde kullanılabilir.
BallpointBen

46

Onu kullanma şeklim

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

Veya

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

SONUÇ:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign

5
Merhaba @Nabin, Bu, Pandalar ve Numpy üzerinde çalışan herkes için çok açık :-)
Vetrivel PS

44

Pandalarda, inplace = True zararlı olarak kabul edilir mi, değil mi?

TLDR; Evet evet o.

  • inplace, adın ima ettiğinin aksine, genellikle kopyaların oluşturulmasını engellemez ve (neredeyse) hiçbir zaman herhangi bir performans avantajı sunmaz
  • inplace yöntem zincirleme ile çalışmıyor
  • inplace yeni başlayanlar için yaygın bir tuzaktır, bu nedenle bu seçeneğin kaldırılması API'yi basitleştirecektir.

Çok az amaca hizmet ettiği için bu parametrenin ayarlanmasını önermiyorum . Bağımsız değişkenin api genelinde kullanımdan kaldırılmasını öneren bu GitHub sorununa bakın inplace.

Kullanmanın inplace=Truedaha verimli veya optimize edilmiş koda yol açacağı yaygın bir yanılgıdır . Gerçekte, kullanmanın kesinlikle hiçbir performans avantajı yokturinplace=True . Hem yerinde hem de yerinde olmayan sürümler, her durumda verilerin bir kopyasını oluşturur ve yerinde sürüm kopyayı otomatik olarak geri atar.

inplace=Trueyeni başlayanlar için yaygın bir tuzaktır. Örneğin, şunları tetikleyebilirSettingWithCopyWarning :

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

DataFrame sütununda bir işlevi çağırmak inplace=True işe yarayabilir veya çalışmayabilir . Bu, özellikle zincirleme indeksleme söz konusu olduğunda geçerlidir.

Yukarıda açıklanan sorunlar yeterli değilmiş gibi yöntem zinciriniinplace=True de engeller . İşleyişine kontrast

result = df.some_function1().reset_index().some_function2()

Aksine

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

İlki, daha iyi bir kod organizasyonu ve okunabilirlik sağlar.


Diğer bir destekleyici iddia, API'sinin set_axisyakın zamanda, inplacevarsayılan değerin True'dan False'a değiştirildiği şekilde değiştirilmiş olmasıdır . GH27600'e bakın . Harika iş geliştiriciler!


Elbette inplace=Truezincirleme vb. İle işe yaramaz, ancak bu, kavramsal olarak ne yaptığını anladığınız açıktır. Kişisel olarak, atamadan kaçınmak için biraz daha temiz buluyorum - Siz de list.sortstandart kitaplıktan vb . Kaldırmaktan yana olur musunuz?
Chris_Rands

4
Bunun adil bir karşılaştırma olduğunu sanmıyorum. Sıralanmış yerine list.sort kullanmanın bazı belirgin faydaları vardır. Aynısı diğer yerinde işlevler için de geçerlidir. Burada gerçek bir fayda yok, yöntem zincirleme pandalarda çok daha yaygındır ve yine de bu argümanın kullanımdan kaldırılması için planlar vardır.
cs95

Ayrıca, atamadan kaçınmayı biraz daha temiz buluyorum: ayrıca, örneğin, python list.append()da yerinde, pandas df.append değil (ve inplace bile desteklemiyor), bu beni sonsuza kadar rahatsız ediyor. İşte bu yüzden bilmek istiyorum, sadece gerçek faydaların ne olduğunu anlamak için - atamadan kaçınmak dışında list.sort ve sort kullanmanın bariz faydaları nelerdir? Aksi takdirde, bence burada gerçek bir fayda var - kişisel olarak daha okunaklı bulduğum bir görevden kaçınabilmem.
sdbbs

1
@sdbbs list.append()var olan bir listeye eklenir . df.appendverilerinizin bir kopyasını oluşturur (5 satırınız veya 5 milyonunuz olması fark etmez), ardından kopyanıza yeni bir satır ekler ve sonra onu döndürür. Sence daha mantıklı olan nedir? Df.append'e gelince, MÜMKÜN OLDUĞU KADAR KAÇININIZ . İnplace = True için tartışmanın iyi bir örnek olduğunu düşünmüyorum, API'de bu fonksiyonun bir yeri olduğunu bile düşünmüyorum.
cs95

6

inplaceparametresi:

df.dropna(axis='index', how='all', inplace=True)

içinde Pandasve genel yollarla:

1. Pandalar, orijinal verilerin bir kopyasını oluşturur

2. ... üzerinde biraz hesaplama yapıyor

3. ... sonuçları orijinal verilere atar.

4. ... kopyayı siler.

Cevabımın geri kalanında aşağıda okuyabileceğiniz gibi, bu parametreyi kullanmak için hala iyi bir nedenimiz olabilir , yani inplace operations, ancak daha fazla sorun oluşturduğundan, mümkünse bundan kaçınmalıyız, örneğin:

1. Kodunuzda hata ayıklamak daha zor olacaktır (Aslında AyarlamawithCopyWarning sizi bu olası soruna karşı uyarmak anlamına gelir)

2. Yöntem zincirleme ile çelişki


Öyleyse onu kullanmamız gereken bir durum var mı?

Kesinlikle evet. Büyük veri kümelerini işlemek için panda veya herhangi bir araç kullanırsak, bazı büyük verilerin tüm belleğimizi tüketebileceği durumla kolayca yüzleşebiliriz. Bu istenmeyen etkiyi önlemek için, yöntem zincirleme gibi bazı teknikler kullanabiliriz :

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

Bu, kodumuzu daha kompakt hale getirir (yine de yorumlanması ve hata ayıklaması daha zor) ve zincirleme yöntemler diğer yöntemin döndürülen değerleriyle çalıştığı için daha az bellek tüketir, böylece girdi verilerinin yalnızca bir kopyası elde edilir. Bu işlemlerden sonra 2 kat orijinal veri hafıza tüketimimiz olacağını açıkça görebiliyoruz .

Veya inplaceparametre kullanabiliriz (yine de yorumlaması ve hata ayıklaması daha zordur) bellek tüketimimiz 2 x orijinal veri olacaktır , ancak bu işlemden sonra bellek tüketimimiz 1 x orijinal veri olarak kalır ; bu, biri büyük veri kümeleriyle çalıştığında tam olarak bilirse büyük fayda.


Final sonucu:

Çok inplacebüyük verilerle çalışmadığınız sürece parametre kullanmaktan kaçının ve yine de kullanılması durumunda olası sorunlarının farkında olun.


2

Aynı değişkene kaydedin

data["column01"].where(data["column01"]< 5, inplace=True)

Ayrı bir değişkene kaydedin

data["column02"] = data["column01"].where(data["column1"]< 5)

Ancak, her zaman değişkenin üzerine yazabilirsiniz

data["column01"] = data["column01"].where(data["column1"]< 5)

Bilginize: Varsayılan olarak inplace = False


1

Bir işlev kullanarak Pandas veri çerçevesinde değişiklik yapmaya çalışırken, değişiklikleri veri çerçevesine uygulamak istiyorsak 'inplace = True' kullanırız. Bu nedenle, aşağıdaki kodun ilk satırı "df" deki ilk sütunun adını "Notlar" olarak değiştirir. Elde edilen veritabanını görmek istiyorsak veritabanını aramamız gerekir.

df.rename(columns={0: 'Grades'}, inplace=True)
df

Değişiklikleri uygulamak istemediğimizde, ancak sadece elde edilen veritabanını yazdırdığımızda 'inplace = False' (bu aynı zamanda varsayılan değerdir) kullanırız. Bu nedenle, gerçekte, orijinal veritabanının, taahhüt edilen değişikliklerle birlikte bir kopyası, orijinal veritabanını değiştirmeden yazdırılır.

Daha açık olmak gerekirse, aşağıdaki kodlar aynı şeyi yapar:

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}

0

inplace=True orijinal df'de değişiklik yapmak isteyip istemediğinize bağlı olarak kullanılır.

df.drop_duplicates()

sadece düşen değerlerin bir görünümünü yapacak, ancak df'de herhangi bir değişiklik yapmayacak

df.drop_duplicates(inplace  = True)

değerleri düşürür ve df'de değişiklikler yapar.

Bu yardımcı olur umarım.:)


0

inplace=Trueişlevi safsız hale getirir. Orijinal veri çerçevesini değiştirir ve Hiçbiri döndürür. Bu durumda DSL zincirini kırarsınız. Veri çerçeve işlevlerinin çoğu yeni bir veri çerçevesi döndürdüğünden, DSL'i rahatlıkla kullanabilirsiniz. Sevmek

df.sort_values().rename().to_csv()

inplace=TrueYok dönüşlü işlev çağrısı ve DSL zinciri bozuk. Örneğin

df.sort_values(inplace=True).rename().to_csv()

atacak NoneType object has no attribute 'rename'

Python'un yerleşik sıralama ve sıralama ile benzer bir şey. yeni bir liste lst.sort()döndürür Noneve sorted(lst)döndürür.

Genel olarak, bunu yapmak inplace=Trueiçin özel bir nedeniniz olmadıkça kullanmayın . Yeniden atama kodunu yazmanız gerektiğinde df = df.sort_values(), işlev çağrısını DSL zincirine eklemeyi deneyin, örn.

df = pd.read_csv().sort_values()...

Doğru biçimlendirmeye sahip tam çalışma kodu sağlamak, kullanıcıların yanıtınızı daha hızlı anlamalarına gerçekten yardımcı olacaktır. Senden aynısını yapmanı rica ediyorum. Ben bir panda uzmanı değilim, bu yüzden yanıtınızı yeniden biçimlendiremem, ancak şiddetle tavsiye edilir,
Anand Vaidya

0

Pandalar konusundaki deneyimime cevap vermek isterim.

'Yerinde = Doğru' argümanı, veri çerçevesinin değişiklikleri kalıcı yapması gerektiği anlamına gelir, örn.

    df.dropna(axis='index', how='all', inplace=True)

aynı veri çerçevesini değiştirir (çünkü bu pandalar NaN girişlerini dizinde bulur ve bırakır). Denersek

    df.dropna(axis='index', how='all')

Pandalar, yaptığımız değişikliklerle veri çerçevesini gösterir, ancak orijinal veri çerçevesi 'df'yi değiştirmeyecektir.


0

İnplace = True kullanmıyorsanız veya inplace = False kullanıyorsanız, temelde bir kopyasını geri alırsınız.

Yani örneğin:

testdf.sort_values(inplace=True, by='volume', ascending=False)

yapıyı azalan sırada sıralanmış verilerle değiştirir.

sonra:

testdf2 = testdf.sort_values( by='volume', ascending=True)

testdf2'yi bir kopya yapacaktır. değerlerin hepsi aynı olacak ancak sıralama tersine çevrilecek ve bağımsız bir nesneye sahip olacaksınız.

sonra başka bir sütun verildiğinde, LongMA deyin ve şunu yapın:

testdf2.LongMA = testdf2.LongMA -1

testdf'deki LongMA sütunu orijinal değerlere sahip olacak ve testdf2 de suçsuz değerlere sahip olacaktır.

Hesaplama zinciri büyüdükçe ve veri çerçevelerinin kopyalarının kendi yaşam döngüleri varken farkı takip etmek önemlidir.


0

Evet, Pandalarda birçok işleve sahibiz parametreye sahiptir, inplaceancak varsayılan olarak atanmıştır False.

Yani df.dropna(axis='index', how='all', inplace=False)bunu yaptığınızda orijinali değiştirmek istemediğinizi düşünür DataFrame, bu nedenle sizin için gerekli değişikliklerle yeni bir kopya oluşturur .

Ancak, inplaceparametreyi olarak değiştirdiğinizdeTrue

O zaman bunun DataFrameyerine yeni bir kopyasını istemediğimi açıkça söylemekle eşdeğerdir.DataFrame

Bu kuvvetler Python yorumlayıcısı için değil , yeni bir oluşturmak içinDataFrame

Ancak inplace, sonucu orijinal DataFrame'e yeniden atayarak da parametreyi kullanmaktan kaçınabilirsiniz.

df = df.dropna(axis='index', how='all')

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.