Pandalardaki belirli sütunları yeniden adlandır


182

Adlı bir veri çerçevem ​​var data. Tek bir sütun başlığını nasıl yeniden adlandırabilirim? Örneğin gdpiçin log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

7
Kesinlikle üst üste binme var, ancak "Pandalardaki sütunları yeniden adlandırma" dan yeniden adlandırmak için tek bir sütun öğesini tek tek belirleyebileceğiniz hemen anlaşılmadı. Tabii ki, geçmişe bakıldığında bu açıktır ve daha derine inmiş olsaydım muhtemelen bunu anlardım, ama bu soru / cevabın bunu belirtmekte daha iyi olduğunu düşünüyorum.
jeremiahbuddha

Yanıtlar:


360
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

renameBunun için bir param olarak dicti kabul ettiği gösteri columnssadece tek bir girişle bir dicti geçmesi böylece.

Ayrıca ilgili


3
Bu büyük bir veri çerçevesi üzerinde çok uzun zaman alıyor, bu yüzden bu tüm veri çerçevesini bellekte bir tür kopyalama inanıyorum?
elgehelge

1
@elgehelge yapmamalı, çoğu panda operasyonu bir kopyasını geri gönderecek ve bazıları bir inplaceparam kabul edecek , eğer bu param görmezden geliyorsa bu bir hatadır, param ile ve param olmadan zamanlamalar yapabilir misiniz, ayrıca böyle bir şey deneyin new_df = df.rename(columns={'new_name':'old_name'})ve bunun olup olmadığını görün daha hızlı ya da değil
15:15

1
@ EdChum Teşekkürler. Çıkarma inplaceparam neredeyse 26 saniyeye 14 saniye arasında süre iki katına çıktı. Ancak 14 saniye sadece başlığı değiştirmek için hala oldukça uzun bir süre ..
elgehelge

2
sadece bir not, dikkat! hedef sütun yoksa, (adın yanlış yazılması vb.) hiçbir hata veya uyarı olmadan hiçbir şey yapmaz.
Amir

1
@Quastiat, bir liste kavrayışı yaparak bu basit operasyonlardan bazılarının neden daha hızlı olduğunu biraz üzüyor. Temel olarak, çok büyük bir
df'niz yoksa

27

list-comprehensionTek bir sütunu yeniden adlandırmanız gerekiyorsa, çok daha hızlı bir uygulama kullanmak olacaktır.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Birden çok sütunu yeniden adlandırmak gerekirse, aşağıdakilerden biri gibi koşullu ifadeler kullanın:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Veya, a'yı kullanarak bir eşleme oluşturun dictionaryve varsayılan değeri eski ad olarak ayarlayarak işlemiyle list-comprehensionbirlikte gerçekleştirin get:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Zamanlamaları:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop

Bu yöntemi kullanmak isterdim, ama ne yazık ki işe yaramaz pd.merge_asof()çünkü bir ifade :(.
thdoan

14

Pandalarda belirli bir sütunu nasıl yeniden adlandırabilirim?

V0.24 + 'dan, aynı anda bir (veya daha fazla) sütunu yeniden adlandırmak için,

TÜM sütunları bir defada yeniden adlandırmanız gerekirse,

  • DataFrame.set_axis()yöntemi ile axis=1. Liste benzeri bir sıra iletin. Yerinde değişiklik için de seçenekler mevcuttur.

rename ile axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

0.21+ ile artık aşağıdakileri axisiçeren bir parametre belirleyebilirsiniz rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

( renameVarsayılan olarak yerinde olmadığına dikkat edin, bu nedenle sonucu tekrar atamanız gerekir .)

Bu ekleme, API'nın geri kalanıyla tutarlılığı artırmak için yapılmıştır. Yeni axisargüman columnsparametreye benzer - aynı şeyi yaparlar.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename ayrıca her sütun için bir kez çağrılan bir geri çağrıyı kabul eder.

df.rename(lambda x: x[0], axis=1)
# df.rename(lambda x: x[0], axis='columns')

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Bu özel senaryo için şunu kullanmak istersiniz:

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

replacePython'daki dizeler yöntemine benzer şekilde , pandalar Dizin ve Serileri (yalnızca nesne türü) str.replace, dize ve normal ifade tabanlı değiştirme için bir ("vektörize") yöntem tanımlar .

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

Bunun diğer yöntemlere göre avantajı str.replaceregex'i desteklemesidir (varsayılan olarak etkindir). Daha fazla bilgi için dokümanlara bakın.


Bir liste geçirilmesi set_axisileaxis=1

set_axisBaşlık listesi ile arayın . Liste, sütun / dizin boyutuna eşit olmalıdır. set_axisorijinal DataFrame'i varsayılan olarak değiştirir, ancak inplace=Falsedeğiştirilmiş bir kopyayı döndürmeyi belirtebilirsiniz .

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Not: Gelecek sürümlerde inplacevarsayılan olarak True.

Yöntem Zinciri
Neden set_axissütun atamanın etkili bir yolunu seçtiğimizi neden seçmelisiniz df.columns = ...? Ted Petrou tarafından [bu cevap] 'da gösterildiği gibi, ( https://stackoverflow.com/a/46912050/4909087 ) set_axisyöntemleri zincirlemeye çalışırken kullanışlıdır.

Karşılaştırmak

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

Karşı

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

Birincisi daha doğal ve serbest akan sözdizimidir.


3

Pandalarda belirli sütunları yeniden adlandırmanın en az beş farklı yolu vardır ve bunları orijinal yanıtlara bağlantılar ile birlikte aşağıda listeledim. Ayrıca bu yöntemleri zamanladım ve aynı şeyi yapmaları için buldum (veri kümenize ve senaryoya bağlı olarak YMMV olsa da). Aşağıdaki test durumu sütunları yeniden adlandırmak etmektir A M N ZiçinA2 M2 N2 Z2 sütunlu bir dataframe içinde Aiçin Zbir milyon satır içeren.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Çıktı:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Sizin için en sezgisel olan ve uygulamanızda uygulaması en kolay olan yöntemi kullanın.

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.