1つの割り当てで複数の列をパンダデータフレームに追加する方法


122

私はパンダが初めてで、複数の列をパンダに同時に追加する方法を理解しようとしています。ここでどんな助けでもありがたいです。理想的には、これを複数のステップを繰り返すのではなく、1つのステップで実行したいと思います...

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...

どのエラーが発生したかを説明する必要があります。私はパンダ1.0でこれをしようとすると、私は取得KeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"
SMCI

回答:


185

私はあなたの構文もうまくいくと思っていたでしょう。column-list構文(df[[new1, new2]] = ...)、パンダでは右側がDataFrameである必要がある DataFrameの列が列と同じ名前であるかどうかは実際には問題ではないことに注意してください)あなたが作成しています)。

構文は既存の列にスカラー値を割り当てるためにうまく機能し、pandasも単一列構文(df[new1] = ...)を使用して新しい列にスカラー値を割り当てます。したがって、解決策は、これをいくつかの単一列の割り当てに変換するか、右側に適切なDataFrameを作成することです。

ここではいくつかのアプローチですます仕事は:

import pandas as pd
import numpy as np

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

次に、次のいずれか:

1)リストのアンパックを使用して、1つの3つの割り当て:

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

2)DataFrameインデックスに一致するように単一の行を拡張するので、これを行うことができます:

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

3)新しい列で一時データフレームを作成し、後で元のデータフレームと結合します。

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)前と同様ですが、join代わりに使用しますconcat(効率が低下する可能性があります):

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

5)辞書を使用することは、前の2つよりも新しいデータフレームを作成するためのより「自然な」方法ですが、新しい列はアルファベット順にソートされます(少なくともPython 3.6または3.7より前)。

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

6).assign()複数の列引数とともに使用します。

私は@zeroの回答でこのバリアントを非常に気に入っていますが、以前のバージョンと同様に、少なくとも初期バージョンのPythonでは、新しい列は常にアルファベット順にソートされます。

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

7)これは興味深い(https://stackoverflow.com/a/44951376/3830997に基づく)が、問題の発生時期がいつになるかわかりません。

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)結局、3つの別々の課題に勝つことは困難です。

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

注:これらのオプションの多くは、すでに他の回答でカバーされています:DATAFRAMEに複数の列を追加し、それらを既存の列に等しく設定それはパンダのデータフレームに一度に複数の列を追加することは可能ですか?複数の空の列をpandas DataFrame追加します


アプローチ#7(.reindex)はデータフレームのインデックスを変更しませんか?なぜ誰かが...列を追加するとき、それは明確な目標でない限り、不インデックスを変更したい
アキュメナス

1
.reindex()columns引数とともに使用されるため、列の「インデックス」(名前)のみが変更されます。行インデックスは変更されません。
マティアスフリップ

一部のアプローチでは、次を使用できますOrderedDict。たとえば、df.join(pd.DataFrame( OrderedDict([('column_new_2', 'dogs'),('column_new_1', np.nan),('column_new_3', 3)]), index=df.index ))
hashmuke

@hashmukeこれはPythonの初期バージョンでは理にかなっています。それは例えば、パンダで複数のもののための辞書を使っている人に特に上訴することができるdf = pd.DataFrame({'before': [1, 2, 3], 'after': [4, 5, 6]})df = pd.DataFrame(OrderedDict([('before', [1, 2, 3]), ('after', [4, 5, 6])])
マティアス・フリップ

2
オプションをjoinで使用している場合は、インデックスに重複がないことを確認してください(またはreset_index最初に使用してください)。デバッグに数時間節約できるかもしれません。
グイド

40

assign列の名前と値の辞書で使用できます。

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

列の特定の順序を維持する同じことを行う方法はありますか?
user48956 2018年

1
あなたは割り当てを複数回呼び出すことにより、以前のバージョンのPythonで特定の順序を維持することができます: df.assign(**{'col_new_1': np.nan}).assign(**{'col2_new_2': 'dogs'}).assign(**{'col3_new_3': 3})
skasch

9

concatを使用すると:

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

何をしたいのかよくわからない[np.nan, 'dogs',3]。多分今それらをデフォルト値として設定しますか?

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

1つのステップで2番目の部分を実行する方法があった場合-例として、はい、列の定数値。
ランニングバーズ2016

3

リスト内包表記の使用、pd.DataFrameおよびpd.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)

ここに画像の説明を入力してください


3

欠落している列(a、b、c、...)を同じ値で追加すると、ここでは0になり、次のようになりました。

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

これは、受け入れられた回答の2番目のバリアントに基づいています。


0

@Matthias Frippの答え​​でそのoption2を指摘したいだけです

(2)DataFrameがこのように機能するとは必ずしも期待していませんが、

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

パンダ自身のドキュメントhttp://pandas.pydata.org/pandas-docs/stable/indexing.html#basicsにすでに文書化されています

列のリストを[]に渡して、その順序で列を選択できます。列がDataFrameに含まれていない場合、例外が発生します。 この方法で複数の列を設定することもできます。 これは、列のサブセットに変換(インプレース)を適用するのに役立ちます。


これは複数列の割り当てではかなり標準的だと思います。私を驚かせたのはpd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)、インデックスと同じ長さのデータフレーム全体を作成するために指定された1つの行を複製することでした。
Matthias Fripp 2017年

0

空の新しい列を追加したいだけの場合は、インデックスの再作成でうまくいきます

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

完全なコード例

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')

それ以外の場合は、割り当てゼロの回答を求めます


0

「インデックス」などを使用するのが苦手です...以下のように表示されます

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')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.