Bir atamada pandas veri çerçevesine birden çok sütun nasıl eklenir?


122

Pandalar konusunda yeniyim ve pandalara aynı anda birden fazla sütun eklemeyi bulmaya çalışıyorum. Buradaki herhangi bir yardım için minnettarız. İdeal olarak, bunu birden fazla tekrarlanan adım yerine tek adımda yapmak isterim ...

import pandas as pd

df = {'col_1': [0, 1, 2, 3],
        'col_2': [4, 5, 6, 7]}
df = pd.DataFrame(df)

df[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs',3]  #thought this would work here...

Hangi hatayı aldığınızı belirtmelisiniz. Bunu pandalar 1.0'da denediğimde alıyorumKeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"
smci

Yanıtlar:


187

Sözdiziminizin de çalışmasını beklerdim. Sorun, sütun listesi sözdizimi ( df[[new1, new2]] = ...) ile yeni sütunlar oluşturduğunuzda , pandaların sağ tarafın bir DataFrame olmasını gerektirmesi nedeniyle ortaya çıkar ( DataFrame'in sütunlarının sütunlarla aynı adlara sahip olmasının aslında önemli olmadığını unutmayın. yaratıyorsun).

Sözdiziminiz, mevcut sütunlara skaler değerler atamak için iyi çalışır ve pandalar da tek sütunlu sözdizimini ( df[new1] = ...) kullanarak yeni bir sütuna skaler değerler atamaktan memnuniyet duyar . Dolayısıyla çözüm, bunu birkaç tek sütunlu atamaya dönüştürmek veya sağ taraf için uygun bir DataFrame oluşturmaktır.

İşte birkaç yaklaşımlardır olacaktır çalışır:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'col_1': [0, 1, 2, 3],
    'col_2': [4, 5, 6, 7]
})

Ardından aşağıdakilerden biri:

1) Listeyi açarak üç ödev bir arada:

df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]

2) DataFrametek bir satırı dizine uyacak şekilde rahatça genişletir, böylece bunu yapabilirsiniz:

df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)

3) Yeni sütunlarla geçici bir veri çerçevesi oluşturun, ardından orijinal veri çerçevesiyle daha sonra birleştirin:

df = pd.concat(
    [
        df,
        pd.DataFrame(
            [[np.nan, 'dogs', 3]], 
            index=df.index, 
            columns=['column_new_1', 'column_new_2', 'column_new_3']
        )
    ], axis=1
)

4) Bir öncekine benzer, ancak joinyerine kullanmak concat(daha az verimli olabilir):

df = df.join(pd.DataFrame(
    [[np.nan, 'dogs', 3]], 
    index=df.index, 
    columns=['column_new_1', 'column_new_2', 'column_new_3']
))

5) Yeni veri çerçevesini oluşturmanın önceki ikisinden daha "doğal" bir yoludur, ancak yeni sütunlar alfabetik olarak sıralanacaktır (en azından Python 3.6 veya 3.7'den önce ):

df = df.join(pd.DataFrame(
    {
        'column_new_1': np.nan,
        'column_new_2': 'dogs',
        'column_new_3': 3
    }, index=df.index
))

6) .assign()Birden çok sütun argümanıyla kullanın .

@ Zero'nun cevabındaki bu değişkeni çok beğeniyorum, ancak öncekinde olduğu gibi, yeni sütunlar her zaman alfabetik olarak sıralanacak, en azından Python'un ilk sürümlerinde:

df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3)

7) Bu ilginç ( https://stackoverflow.com/a/44951376/3830997'ye göre ), ancak ne zaman zahmete değeceğini bilmiyorum:

new_cols = ['column_new_1', 'column_new_2', 'column_new_3']
new_vals = [np.nan, 'dogs', 3]
df = df.reindex(columns=df.columns.tolist() + new_cols)   # add empty cols
df[new_cols] = new_vals  # multi-column assignment works for existing cols

8) Sonunda, üç ayrı görevi bitirmek zor:

df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3

Not: Bu seçeneklerin birçoğu zaten diğer yanıtlar örtülü edilmiştir: DataFrame için birden çok sütun ekleyin ve bunları varolan kolona eşit seti , bir pandalar DataFrame için aynı anda birden sütunlar eklemek mümkün mü? , Pandalar DataFrame'e birden çok boş sütun ekleyin


# 7 ( .reindex) yaklaşımı veri çerçevesinin dizinini değiştirmez mi? Açık bir hedef olmadıkça neden birisi sütun eklerken dizini gereksiz yere değiştirmek
istesin ki

1
.reindex()columnsbağımsız değişkenle birlikte kullanılır , bu nedenle yalnızca "dizin" (adlar) sütununu değiştirir. Satır dizinini değiştirmez.
Matthias Fripp

bazı yaklaşımlar OrderedDictiçin şunları kullanabilirsiniz : örneğin,df.join(pd.DataFrame( OrderedDict([('column_new_2', 'dogs'),('column_new_1', np.nan),('column_new_3', 3)]), index=df.index ))
hashmuke

@hashmuke Bu, Python'un ilk sürümleri için mantıklı. Bu örneğin, Pandalar birden şeyler için sözlükleri kullanan kişilere özellikle hitap edebilir df = pd.DataFrame({'before': [1, 2, 3], 'after': [4, 5, 6]})vsdf = pd.DataFrame(OrderedDict([('before', [1, 2, 3]), ('after', [4, 5, 6])])
Matthias Fripp

2
Seçeneği ile kullanıyorsanız, joindizininizde kopya bulunmadığından emin olun (veya bir reset_indexilk kullanın ). Hata ayıklamada size birkaç saat kazandırabilir.
Guido

40

Bir assigndizi sütun adı ve değeri ile kullanabilirsiniz.

In [1069]: df.assign(**{'col_new_1': np.nan, 'col2_new_2': 'dogs', 'col3_new_3': 3})
Out[1069]:
   col_1  col_2 col2_new_2  col3_new_3  col_new_1
0      0      4       dogs           3        NaN
1      1      5       dogs           3        NaN
2      2      6       dogs           3        NaN
3      3      7       dogs           3        NaN

Sütunların belirli bir sırasını koruyan aynısını yapmanın bir yolu var mı?
user48956

1
df.assign(**{'col_new_1': np.nan}).assign(**{'col2_new_2': 'dogs'}).assign(**{'col3_new_3': 3})
Atamayı

Sütun adları yalnızca yasal değişken isimleri dizeleri içeriyorsa: df.assign(col_new_1=np.nan, col2_new_2='dogs', col3_new_3=3). Bu düzeni korur.
Tobias Bergkvist

9

Concat kullanımı ile :

In [128]: df
Out[128]: 
   col_1  col_2
0      0      4
1      1      5
2      2      6
3      3      7

In [129]: pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])])
Out[129]: 
   col_1  col_2 column_new_1 column_new_2 column_new_3
0    0.0    4.0          NaN          NaN          NaN
1    1.0    5.0          NaN          NaN          NaN
2    2.0    6.0          NaN          NaN          NaN
3    3.0    7.0          NaN          NaN          NaN

Ne yapmak istediğinden pek emin değilim [np.nan, 'dogs',3]. Belki şimdi bunları varsayılan değerler olarak ayarlayın?

In [142]: df1 = pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])])
In [143]: df1[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs', 3]

In [144]: df1
Out[144]: 
   col_1  col_2  column_new_1 column_new_2  column_new_3
0    0.0    4.0           NaN         dogs             3
1    1.0    5.0           NaN         dogs             3
2    2.0    6.0           NaN         dogs             3
3    3.0    7.0           NaN         dogs             3

2. bölümünüzü tek adımda yapmanın bir yolu varsa - evet örnek olarak sütunlardaki sabit değerler.
runningbirds

3

liste anlama kullanımı pd.DataFramevepd.concat

pd.concat(
    [
        df,
        pd.DataFrame(
            [[np.nan, 'dogs', 3] for _ in range(df.shape[0])],
            df.index, ['column_new_1', 'column_new_2','column_new_3']
        )
    ], axis=1)

görüntü açıklamasını buraya girin


3

aynı değere sahip çok sayıda eksik sütun (a, b, c, ....) ekliyorsanız, burada 0, bunu yaptım:

    new_cols = ["a", "b", "c" ] 
    df[new_cols] = pd.DataFrame([[0] * len(new_cols)], index=df.index)

Kabul edilen cevabın ikinci varyantına dayanmaktadır.


0

@Matthias Fripp'in cevabında bu seçenek2'yi belirtmek istiyorum

(2) DataFrame'in bu şekilde çalışmasını beklemiyordum, ancak

df [['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame ([[np.nan, 'köpekler', 3]], indeks = df.index)

pandaların kendi belgelerinde zaten belgelenmiştir http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

Sütunları bu sırayla seçmek için [] 'ye bir sütun listesi geçirebilirsiniz. DataFrame'de bir sütun yoksa, bir istisna ortaya çıkar. Bu şekilde birden çok sütun da ayarlanabilir. Bunu , sütunların bir alt kümesine bir dönüşüm ( yerinde ) uygulamak için yararlı bulabilirsiniz .


Bunun çok sütunlu atamalar için oldukça standart olduğunu düşünüyorum. Beni şaşırtan kısım pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index), indeksle aynı uzunlukta bütün bir veri çerçevesi oluşturmak için verilen bir satırı kopyalamasıydı.
Matthias Fripp

0

Yalnızca boş yeni sütunlar eklemek istiyorsanız, reindex işinizi yapar

df
   col_1  col_2
0      0      4
1      1      5
2      2      6
3      3      7

df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)
   col_1  col_2  column_new_1  column_new_2  column_new_3
0      0      4           NaN           NaN           NaN
1      1      5           NaN           NaN           NaN
2      2      6           NaN           NaN           NaN
3      3      7           NaN           NaN           NaN

tam kod örneği

import numpy as np
import pandas as pd

df = {'col_1': [0, 1, 2, 3],
        'col_2': [4, 5, 6, 7]}
df = pd.DataFrame(df)
print('df',df, sep='\n')
print()
df=df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)
print('''df.reindex(list(df)+['column_new_1', 'column_new_2','column_new_3'], axis=1)''',df, sep='\n')

aksi halde atama ile sıfır cevabı ver


0

"Dizin" kullanmakta rahat değilim ve benzeri ... aşağıdaki gibi gelebilir

df.columns
Index(['A123', 'B123'], dtype='object')

df=pd.concat([df,pd.DataFrame(columns=list('CDE'))])

df.rename(columns={
    'C':'C123',
    'D':'D123',
    'E':'E123'
},inplace=True)


df.columns
Index(['A123', 'B123', 'C123', 'D123', 'E123'], dtype='object')
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.