Ajout d'une nouvelle colonne à DataFrame existant dans les pandas Python

980

J'ai le DataFrame indexé suivant avec des colonnes et des lignes nommées, des nombres non continus:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Je voudrais ajouter une nouvelle colonne 'e',, au bloc de données existant et je ne veux rien changer dans le bloc de données (c'est-à-dire que la nouvelle colonne a toujours la même longueur que le DataFrame).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

Comment puis-je ajouter une colonne eà l'exemple ci-dessus?

tomasz74
la source

Réponses:

1043

Utilisez les index df1 d'origine pour créer la série:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)

Edit 2015
Certains ont rapporté avoir obtenu SettingWithCopyWarningce code.
Cependant, le code fonctionne toujours parfaitement avec la version actuelle 0.16.1 des pandas.

>>> sLength = len(df1['a'])
>>> df1
          a         b         c         d
6 -0.269221 -0.026476  0.997517  1.294385
8  0.917438  0.847941  0.034235 -0.448948

>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e
6 -0.269221 -0.026476  0.997517  1.294385  1.757167
8  0.917438  0.847941  0.034235 -0.448948  2.228131

>>> p.version.short_version
'0.16.1'

L' SettingWithCopyWarningobjectif est d'informer d'une cession éventuellement invalide sur une copie du Dataframe. Cela ne signifie pas nécessairement que vous l'avez mal fait (cela peut déclencher de faux positifs) mais à partir de la version 0.13.0, il vous indique qu'il existe des méthodes plus adéquates pour le même objectif. Ensuite, si vous recevez l'avertissement, suivez simplement son conseil: Essayez d'utiliser .loc [row_index, col_indexer] = value à la place

>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e         f
6 -0.269221 -0.026476  0.997517  1.294385  1.757167 -0.050927
8  0.917438  0.847941  0.034235 -0.448948  2.228131  0.006109
>>> 

En fait, c'est actuellement la méthode la plus efficace décrite dans les documents pandas


Modifier 2017

Comme indiqué dans les commentaires et par @Alexander, actuellement la meilleure méthode pour ajouter les valeurs d'une série en tant que nouvelle colonne d'un DataFrame pourrait utiliser assign:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
joaquin
la source
24
si vous devez ajouter une colonne à l'avance, utilisez DataFrame.insert: df1.insert (0, 'A', Series (np.random.randn (sLength), index = df1.index))
lowtech
29
À partir de la version 0.12 de Pandas, je pense que cette syntaxe n'est pas optimale et donne un avertissement:SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
Zhubarb
6
Suivre .loc comme avertissement SettingWithCopy entraîne en quelque sorte plus d'avertissement: ... self.obj [item_labels [indexer [info_axis]]] = value
seongjoo
12
@toto_tico Vous pouvez décompresser un kwargsdictionnaire, comme ceci:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
TC Proctor
23
Au lieu de dire "actuellement" ou de référencer des années, veuillez faire référence aux numéros de version des pandas, par exemple "entre 0.14-0.16 do X, dans 0.17+ do Y ..."
smci
229

Voici le moyen simple d'ajouter une nouvelle colonne: df['e'] = e

Kathirmani Sukumar
la source
154
Malgré le nombre élevé de votes: cette réponse est fausse . Notez que l'OP a une trame de données avec des index non continus et e( Series(np.random.randn(sLength))) génère une série 0-n indexée. Si vous attribuez cela à df1, vous obtenez des cellules NaN.
joaquin
32
Ce que dit @joaquin est vrai, mais tant que vous gardez cela à l'esprit, c'est un raccourci très utile.
VedTopkar
2
@Eric Leschinski: Je ne sais pas comment vous éditez vous aidera pour cette question. my_dataframe = pd.DataFrame(columns=('foo', 'bar')). Annulation de votre montage
Kathirmani Sukumar
1
Cela n'aide pas, car si vous avez plusieurs lignes et que vous utilisez l'affectation, elle affecte toutes les lignes de la nouvelle colonne avec cette valeur (dans votre cas e), ce qui n'est généralement pas souhaitable.
Paniz
156

Je voudrais ajouter une nouvelle colonne, «e», au bloc de données existant et ne rien changer dans le bloc de données. (La série a toujours la même longueur qu'une trame de données.)

Je suppose que les valeurs d'index ecorrespondent à celles de df1.

La façon la plus simple de lancer une nouvelle colonne nommée eet de lui affecter les valeurs de votre série e:

df['e'] = e.values

assigner (Pandas 0.16.0+)

Depuis Pandas 0.16.0, vous pouvez également utiliser assign, qui attribue de nouvelles colonnes à un DataFrame et renvoie un nouvel objet (une copie) avec toutes les colonnes d'origine en plus des nouvelles.

df1 = df1.assign(e=e.values)

Selon cet exemple (qui inclut également le code source de la assignfonction), vous pouvez également inclure plusieurs colonnes:

df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df.assign(mean_a=df.a.mean(), mean_b=df.b.mean())
   a  b  mean_a  mean_b
0  1  3     1.5     3.5
1  2  4     1.5     3.5

Dans le contexte de votre exemple:

np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
mask = df1.applymap(lambda x: x <-0.7)
df1 = df1[-mask.any(axis=1)]
sLength = len(df1['a'])
e = pd.Series(np.random.randn(sLength))

>>> df1
          a         b         c         d
0  1.764052  0.400157  0.978738  2.240893
2 -0.103219  0.410599  0.144044  1.454274
3  0.761038  0.121675  0.443863  0.333674
7  1.532779  1.469359  0.154947  0.378163
9  1.230291  1.202380 -0.387327 -0.302303

>>> e
0   -1.048553
1   -1.420018
2   -1.706270
3    1.950775
4   -0.509652
dtype: float64

df1 = df1.assign(e=e.values)

>>> df1
          a         b         c         d         e
0  1.764052  0.400157  0.978738  2.240893 -1.048553
2 -0.103219  0.410599  0.144044  1.454274 -1.420018
3  0.761038  0.121675  0.443863  0.333674 -1.706270
7  1.532779  1.469359  0.154947  0.378163  1.950775
9  1.230291  1.202380 -0.387327 -0.302303 -0.509652

La description de cette nouvelle fonctionnalité lors de son introduction peut être trouvée ici .

Alexandre
la source
2
Un commentaire sur les performances relatives des deux méthodes, étant donné que la première méthode ( df['e'] = e.values) ne crée pas de copie de la trame de données, tandis que la deuxième option (en utilisant df.assign) le fait? Dans le cas de nombreuses nouvelles colonnes ajoutées séquentiellement et de grandes trames de données, je m'attendrais à de bien meilleures performances de la première méthode.
jhin
2
@jhin Oui, l'affectation directe est évidemment beaucoup si vous travaillez sur une trame de données fixe. L'avantage d'utiliser assignest de chaîner vos opérations.
Alexander
Cela semble certainement être un bon équilibre entre explicite et implicite. +1: D
Abe Hoffman
2
Pour le plaisirdf.assign(**df.mean().add_prefix('mean_'))
piRSquared
1
@Owlright De la question, il semble que l'OP concatène simplement les trames de données et ignore l'index. Si tel est le cas, les méthodes ci-dessus fonctionneront. Si l'on souhaite conserver l'index, alors utilisez quelque chose comme df_new = pd.concat([df1, df2], axis=1), en notant cela ignore_index=Falsepar défaut.
Alexander
51

Il semble que dans les versions récentes de Pandas, la voie à suivre consiste à utiliser df.assign :

df1 = df1.assign(e=np.random.randn(sLength))

Ça ne produit pas SettingWithCopyWarning.

Mikhail Korobov
la source
1
Copie du commentaire de @smci ci-dessus ... Au lieu de dire "actuellement" ou de faire référence à des années, veuillez faire référence aux numéros de version de Pandas
Kyle C
50

Faire cela directement via NumPy sera le plus efficace:

df1['e'] = np.random.randn(sLength)

Notez que ma suggestion originale (très ancienne) était d'utiliser map(qui est beaucoup plus lente):

df1['e'] = df1['a'].map(lambda x: np.random.random())
Andy Hayden
la source
1
merci pour votre réponse, comme je l'ai déjà fait, ai-je la possibilité de modifier votre code, .mapd'utiliser des séries existantes à la place de lambda? J'essaye df1['e'] = df1['a'].map(lambda x: e)ou df1['e'] = df1['a'].map(e)mais ce n'est pas ce dont j'ai besoin. (Je suis nouveau sur pyhon et votre réponse précédente m'a déjà aidé)
tomasz74
@ tomasz74 si vous avez déjà eune série, vous n'avez pas besoin d'utiliser map, utilisez df['e']=e(réponse @joaquins).
Andy Hayden
49

Affectation de colonne super simple

Une trame de données pandas est implémentée en tant que dictée ordonnée de colonnes.

Cela signifie que le __getitem__ []peut non seulement être utilisé pour obtenir une certaine colonne, mais __setitem__ [] =peut également être utilisé pour affecter une nouvelle colonne.

Par exemple, cette trame de données peut avoir une colonne ajoutée en utilisant simplement l' []accesseur

    size      name color
0    big      rose   red
1  small    violet  blue
2  small     tulip   red
3  small  harebell  blue

df['protected'] = ['no', 'no', 'no', 'yes']

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Notez que cela fonctionne même si l'index de la trame de données est désactivé.

df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

[] = est le chemin à parcourir, mais attention!

Cependant, si vous en avez un pd.Serieset essayez de l'attribuer à une trame de données où les index sont désactivés, vous rencontrerez des problèmes. Voir l'exemple:

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

En effet, un pd.Seriespar défaut a un index énuméré de 0 à n. Et la [] =méthode des pandas essaie d'être "intelligente"

Qu'est-ce qui se passe réellement.

Lorsque vous utilisez la [] =méthode pandas effectue discrètement une jointure externe ou une fusion externe à l'aide de l'index de la trame de données de gauche et de l'index de la série de droite.df['column'] = series

Note de côté

Cela provoque rapidement une dissonance cognitive, car la []=méthode essaie de faire beaucoup de choses différentes en fonction de l'entrée, et le résultat ne peut être prédit que si vous savez simplement comment les pandas fonctionnent. Je déconseille donc les []=bases de code, mais lors de l'exploration de données dans un ordinateur portable, c'est très bien.

Contourner le problème

Si tu as un pd.Series et que vous voulez l'attribuer de haut en bas, ou si vous codez du code productif et que vous n'êtes pas sûr de l'ordre des index, cela vaut la peine de le protéger pour ce type de problème.

Vous pouvez abaisser le pd.Seriesà un np.ndarrayou un list, cela fera l'affaire.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values

ou

df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))

Mais ce n'est pas très explicite.

Un codeur peut venir et dire "Hé, ça a l'air redondant, je vais juste l'optimiser".

Manière explicite

Définir l'index de la pd.Seriespour être l'index de la dfest explicite.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)

Ou plus réaliste, vous en avez probablement pd.Seriesdéjà un disponible.

protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index

3     no
2     no
1     no
0    yes

Peut maintenant être attribué

df['protected'] = protected_series

    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

Moyen alternatif avec df.reset_index()

Puisque la dissonance d'index est le problème, si vous sentez que l'indice de la trame de données ne doit pas dicter les choses, vous pouvez simplement supprimer l'index, cela devrait être plus rapide, mais ce n'est pas très propre, car votre fonction fait maintenant probablement deux choses.

df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Remarque sur df.assign

Bien df.assignque ce soit plus explicite ce que vous faites, il a en fait tous les mêmes problèmes que ci-dessus[]=

df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Attention juste à ce df.assignque votre colonne ne soit pas appelée self. Cela entraînera des erreurs. Cela rend df.assign malodorant , car il existe ce type d'artefacts dans la fonction.

df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'

Vous pouvez dire: «Eh bien, je n'utiliserai tout simplement pas selfalors». Mais qui sait comment cette fonction évoluera à l'avenir pour prendre en charge de nouveaux arguments. Peut-être que le nom de votre colonne sera un argument dans une nouvelle mise à jour de pandas, provoquant des problèmes de mise à niveau.

firelynx
la source
6
" Lorsque vous utilisez la [] =méthode pandas effectue tranquillement une jointure externe ou une fusion externe ". Il s'agit de l'information la plus importante de tout le sujet. Mais pourriez-vous fournir un lien vers la documentation officielle sur le fonctionnement de l' []=opérateur?
Lightman
25

Façons les plus simples: -

data['new_col'] = list_of_values

data.loc[ : , 'new_col'] = list_of_values

De cette façon, vous évitez ce qu'on appelle l'indexation chaînée lors de la définition de nouvelles valeurs dans un objet pandas. Cliquez ici pour lire plus loin .

Abhishek
la source
23

Si vous souhaitez définir la nouvelle colonne entière sur une valeur de base initiale (par exemple, None ), vous pouvez le faire:df1['e'] = None

Cela attribuerait en fait le type "objet" à la cellule. Donc, plus tard, vous êtes libre de mettre des types de données complexes, comme la liste, dans des cellules individuelles.

digdug
la source
1
cela soulève un paramètre withcopywarning
00__00__00
1
df ['E'] = '' fonctionne également si quelqu'un veut ajouter une colonne vide
debaonline4u
22

J'ai été redouté SettingWithCopyWarning, et il n'a pas été corrigé en utilisant la syntaxe iloc. Mon DataFrame a été créé par read_sql à partir d'une source ODBC. En utilisant une suggestion de lowtech ci-dessus, ce qui suit a fonctionné pour moi:

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(sLength),  index=df.index))

Cela a bien fonctionné pour insérer la colonne à la fin. Je ne sais pas si c'est le plus efficace, mais je n'aime pas les messages d'avertissement. Je pense qu'il y a une meilleure solution, mais je ne la trouve pas, et je pense que cela dépend d'un certain aspect de l'index.
Remarque . Que cela ne fonctionne qu'une seule fois et donnera un message d'erreur si vous essayez d'écraser la colonne existante.
Remarque Comme ci-dessus et à partir de 0.16.0, assign est la meilleure solution. Voir la documentation http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Fonctionne bien pour le type de flux de données où vous n'écrasez pas vos valeurs intermédiaires.

hum3
la source
C'est la seule façon qui fonctionne pour moi en 2019!
hydradon
14
  1. Créez d'abord un python contenant list_of_edes données pertinentes.
  2. Utilisez ceci: df['e'] = list_of_e
Sumit Pokhrel
la source
1
Je ne comprends vraiment pas pourquoi ce n'est pas la réponse préférée. Si vous avez un pd.Series, la tolist()commande peut être utile.
So S
11

Si la colonne que vous essayez d'ajouter est une variable série, alors:

df["new_columns_name"]=series_variable_name #this will do it for you

Cela fonctionne bien même si vous remplacez une colonne existante. Tapez simplement le nouveau_nom_colonnes de la même manière que la colonne que vous souhaitez remplacer. Il écrasera simplement les données de colonne existantes par les nouvelles données de série.

Akshay Singhvi
la source
10

Si le bloc de données et l'objet Series ont le même index , pandas.concatfonctionne également ici:

import pandas as pd
df
#          a            b           c           d
#0  0.671399     0.101208   -0.181532    0.241273
#1  0.446172    -0.243316    0.051767    1.577318
#2  0.614758     0.075793   -0.451460   -0.012493

e = pd.Series([-0.335485, -1.166658, -0.385571])    
e
#0   -0.335485
#1   -1.166658
#2   -0.385571
#dtype: float64

# here we need to give the series object a name which converts to the new  column name 
# in the result
df = pd.concat([df, e.rename("e")], axis=1)
df

#          a            b           c           d           e
#0  0.671399     0.101208   -0.181532    0.241273   -0.335485
#1  0.446172    -0.243316    0.051767    1.577318   -1.166658
#2  0.614758     0.075793   -0.451460   -0.012493   -0.385571

Au cas où ils n'auraient pas le même indice:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)
Psidom
la source
10

Infaillible:

df.loc[:, 'NewCol'] = 'New_Val'

Exemple:

df = pd.DataFrame(data=np.random.randn(20, 4), columns=['A', 'B', 'C', 'D'])

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
3  -0.147354  0.778707  0.479145  2.284143
4  -0.529529  0.000571  0.913779  1.395894
5   2.592400  0.637253  1.441096 -0.631468
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
8   0.606985 -2.232903 -1.358107 -2.855494
9  -0.692013  0.671866  1.179466 -1.180351
10 -1.093707 -0.530600  0.182926 -1.296494
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
18  0.693458  0.144327  0.329500 -0.655045
19  0.104425  0.037412  0.450598 -0.923387


df.drop([3, 5, 8, 10, 18], inplace=True)

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
4  -0.529529  0.000571  0.913779  1.395894
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
9  -0.692013  0.671866  1.179466 -1.180351
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
19  0.104425  0.037412  0.450598 -0.923387

df.loc[:, 'NewCol'] = 0

df
           A         B         C         D  NewCol
0  -0.761269  0.477348  1.170614  0.752714       0
1   1.217250 -0.930860 -0.769324 -0.408642       0
2  -0.619679 -1.227659 -0.259135  1.700294       0
4  -0.529529  0.000571  0.913779  1.395894       0
6   0.757178  0.240012 -0.553820  1.177202       0
7  -0.986128 -1.313843  0.788589 -0.707836       0
9  -0.692013  0.671866  1.179466 -1.180351       0
11 -0.143273 -0.503199 -1.328728  0.610552       0
12 -0.923110 -1.365890 -1.366202 -1.185999       0
13 -2.026832  0.273593 -0.440426 -0.627423       0
14 -0.054503 -0.788866 -0.228088 -0.404783       0
15  0.955298 -1.430019  1.434071 -0.088215       0
16 -0.227946  0.047462  0.373573 -0.111675       0
17  1.627912  0.043611  1.743403 -0.012714       0
19  0.104425  0.037412  0.450598 -0.923387       0
K88
la source
2
Pas infaillible. Cela ne répond pas à la question du PO, qui est un cas où les indices de la trame de données existante et de la nouvelle série ne sont pas alignés.
Alexander
7

Permettez-moi d'ajouter que, tout comme pour hum3 , cela .locn'a pas résolu le problème SettingWithCopyWarninget j'ai dû y recourir df.insert(). Dans mon cas, un faux positif a été généré par une "fausse" indexation de chaîne dict['a']['e'], où se 'e'trouve la nouvelle colonne, et dict['a']est un DataFrame provenant du dictionnaire.

Notez également que si vous savez ce que vous faites, vous pouvez désactiver l'avertissement en utilisant pd.options.mode.chained_assignment = None et en utilisant l'une des autres solutions données ici.

kkumer
la source
7

pour insérer une nouvelle colonne à un emplacement donné (0 <= loc <= quantité de colonnes) dans un bloc de données, utilisez simplement Dataframe.insert:

DataFrame.insert(loc, column, value)

Par conséquent, si vous souhaitez ajouter la colonne e à la fin d'une trame de données appelée df , vous pouvez utiliser:

e = [-0.335485, -1.166658, -0.385571]    
DataFrame.insert(loc=len(df.columns), column='e', value=e)

La valeur peut être une série, un entier (auquel cas toutes les cellules sont remplies avec cette seule valeur) ou une structure de type tableau

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html

Nooyi
la source
6

Avant d'affecter une nouvelle colonne, si vous avez indexé des données, vous devez trier l'index. Au moins dans mon cas, j'ai dû:

data.set_index(['index_column'], inplace=True)
"if index is unsorted, assignment of a new column will fail"        
data.sort_index(inplace = True)
data.loc['index_value1', 'column_y'] = np.random.randn(data.loc['index_value1', 'column_x'].shape[0])
Dima Lituiev
la source
6

Une chose à noter, cependant, est que si vous le faites

df1['e'] = Series(np.random.randn(sLength), index=df1.index)

ce sera effectivement une jointure gauche sur le df1.index. Donc, si vous souhaitez avoir un effet de jointure externe , ma solution probablement imparfaite consiste à créer un cadre de données avec des valeurs d'index couvrant l'univers de vos données, puis à utiliser le code ci-dessus. Par exemple,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)
WillZ
la source
5

Je cherchais un moyen général d'ajouter une colonne de numpy.nans à une trame de données sans obtenir le stupideSettingWithCopyWarning .

Parmi les éléments suivants:

  • les réponses ici
  • cette question sur le passage d'une variable comme argument de mot clé
  • cette méthode pour générer un numpytableau de NaN en ligne

Je suis venu avec ceci:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})
ryanjdillon
la source
4

Pour ajouter une nouvelle colonne, «e», au bloc de données existant

 df1.loc[:,'e'] = Series(np.random.randn(sLength))
Chirag
la source
Il donne également le message de mise en garde
B Furtado
vous devez utiliser df1.loc [::, 'e'] = Series (np.random.randn (sLength))
Hermes Morales
4

Par souci d'exhaustivité - encore une autre solution utilisant la méthode DataFrame.eval () :

Les données:

In [44]: e
Out[44]:
0    1.225506
1   -1.033944
2   -0.498953
3   -0.373332
4    0.615030
5   -0.622436
dtype: float64

In [45]: df1
Out[45]:
          a         b         c         d
0 -0.634222 -0.103264  0.745069  0.801288
4  0.782387 -0.090279  0.757662 -0.602408
5 -0.117456  2.124496  1.057301  0.765466
7  0.767532  0.104304 -0.586850  1.051297
8 -0.103272  0.958334  1.163092  1.182315
9 -0.616254  0.296678 -0.112027  0.679112

Solution:

In [46]: df1.eval("e = @e.values", inplace=True)

In [47]: df1
Out[47]:
          a         b         c         d         e
0 -0.634222 -0.103264  0.745069  0.801288  1.225506
4  0.782387 -0.090279  0.757662 -0.602408 -1.033944
5 -0.117456  2.124496  1.057301  0.765466 -0.498953
7  0.767532  0.104304 -0.586850  1.051297 -0.373332
8 -0.103272  0.958334  1.163092  1.182315  0.615030
9 -0.616254  0.296678 -0.112027  0.679112 -0.622436
MaxU
la source
4

Pour créer une colonne vide

df['i'] = None
JNZ
la source
3

Ce qui suit est ce que j'ai fait ... Mais je suis assez nouveau pour les pandas et vraiment Python en général, donc pas de promesses.

df = pd.DataFrame([[1, 2], [3, 4], [5,6]], columns=list('AB'))

newCol = [3,5,7]
newName = 'C'

values = np.insert(df.values,df.shape[1],newCol,axis=1)
header = df.columns.values.tolist()
header.append(newName)

df = pd.DataFrame(values,columns=header)
Devin Charles
la source
3

Si vous obtenez le SettingWithCopyWarning, une solution simple consiste à copier le DataFrame auquel vous essayez d'ajouter une colonne.

df = df.copy()
df['col_name'] = values
fredcallaway
la source
10
ce n'est pas une bonne idée. Si la trame de données est suffisamment grande, cela va être gourmand en mémoire ... De plus, cela se transformerait en cauchemar si vous continuez à ajouter des colonnes de temps en temps.
Kevad