Dodanie nowej kolumny do istniejącej ramki danych w pandach Pythona

978

Mam następujące zindeksowane DataFrame z nazwanymi kolumnami i wierszami nieciągłymi liczbami:

          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

Chciałbym dodać nową kolumnę 'e'do istniejącej ramki danych i nie chcę niczego zmieniać w ramce danych (tj. Nowa kolumna ma zawsze taką samą długość jak ramka danych).

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

Jak mogę dodać kolumnę edo powyższego przykładu?

tomasz74
źródło

Odpowiedzi:

1043

Użyj oryginalnych indeksów df1, aby utworzyć serię:

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

Edytuj 2015
Niektórzy zgłosili, że dostali SettingWithCopyWarningten kod.
Jednak kod nadal działa idealnie z bieżącą wersją pandy 0.16.1.

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

Te SettingWithCopyWarningcele, aby poinformować o możliwie nieprawidłowej cesji na kopię Dataframe. Nie musi to oznaczać, że zrobiłeś to źle (może powodować fałszywe alarmy), ale od 0.13.0 informuje, że istnieją bardziej odpowiednie metody do tego samego celu. Następnie, jeśli pojawi się ostrzeżenie, postępuj zgodnie z jego radą: Spróbuj zamiast tego użyć .loc [row_index, col_indexer] = wartość

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

W rzeczywistości jest to obecnie bardziej wydajna metoda opisana w dokumentach pandas


Edytuj 2017

Jak wskazano w komentarzach i @Alexander, obecnie najlepszą metodą dodawania wartości Serii jako nowej kolumny DataFrame może być assign:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
joaquin
źródło
24
jeśli trzeba poprzedzić użycia kolumna DataFrame.insert: df1.insert (0, 'A', Series (np.random.randn (sLength), index = df1.index))
lowtech
29
Począwszy od wersji 0.12 Pandy, uważam, że ta składnia nie jest optymalna i ostrzega: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
Następujące ostrzeżenie .loc jako SettingWithCopy powoduje w jakiś sposób więcej ostrzeżeń: ... self.obj [item_labels [indexer [info_axis]]] = wartość
seongjoo
12
@toto_tico Możesz rozpakować kwargssłownik, tak jak:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
TC Proctor
23
Zamiast mówić „obecnie” lub odwoływać się do lat, proszę podać numery wersji pand, np. „Między 0,14-0,16 do X, w 0,17+ do Y ...”
smci
229

To prosty sposób dodania nowej kolumny: df['e'] = e

Kathirmani Sukumar
źródło
153
Pomimo dużej liczby głosów: ta odpowiedź jest błędna . Zauważ, że OP ma ramkę danych z nieciągłymi indeksami i e( Series(np.random.randn(sLength))) generuje indeksowane Serie 0-n. Jeśli przypiszesz to do df1, otrzymasz trochę komórek NaN.
joaquin
32
To, co mówi @joaquin, jest prawdą, ale pod warunkiem, że o tym pamiętasz, jest to bardzo przydatny skrót.
VedTopkar
2
@Eric Leschinski: Nie jestem pewien, jak edytujesz, pomoże to pytanie. my_dataframe = pd.DataFrame(columns=('foo', 'bar')).
Cofnij
1
To nie pomaga, ponieważ jeśli masz wiele wierszy i używasz przypisania, przypisuje ono wszystkie wiersze nowej kolumny o tej wartości (w twoim przypadku e), co zwykle jest niepożądane.
Paniz
156

Chciałbym dodać nową kolumnę „e” do istniejącej ramki danych i nie zmieniać niczego w ramce danych. (Seria zawsze ma tę samą długość co ramka danych.)

Zakładam, że wartości indeksu są ezgodne z tymi w df1.

Najprostszym sposobem na zainicjowanie nowej kolumny o nazwie ei przypisanie jej wartości z serii e:

df['e'] = e.values

przypisać (Pandy 0.16.0+)

Począwszy od wersji Panda 0.16.0, można również użyć assign, która przypisuje nowe kolumny do DataFrame i zwraca nowy obiekt (kopię) ze wszystkimi oryginalnymi kolumnami oprócz nowych.

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

Zgodnie z tym przykładem (który zawiera również kod źródłowy assignfunkcji), możesz również dołączyć więcej niż jedną kolumnę:

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

W kontekście twojego przykładu:

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

Opis tej nowej funkcji, która została wprowadzona po raz pierwszy, można znaleźć tutaj .

Alexander
źródło
2
Jakiś komentarz na temat względnej wydajności dwóch metod, biorąc pod uwagę, że pierwsza metoda ( df['e'] = e.values) nie tworzy kopii ramki danych, podczas gdy druga opcja (używa df.assign) robi? W przypadku wielu nowych kolumn dodawanych kolejno i dużych ramek danych oczekiwałbym znacznie lepszej wydajności pierwszej metody.
jhin
2
@jhin Tak, bezpośrednie przypisanie jest oczywiście dużo, jeśli pracujesz na stałej ramce danych. Zaletą użytkowania assignjest połączenie działań.
Alexander
To z pewnością wydaje się być dobrą równowagą między jawnym a niejawnym. +1: D
Abe Hoffman
2
Dla zabawydf.assign(**df.mean().add_prefix('mean_'))
piRSquared,
1
@Owlright Z pytania wynika, że ​​OP po prostu konkatenuje ramki danych i ignoruje indeks. W takim przypadku powyższe metody będą działać. Jeśli ktoś chce zachować indeks, należy użyć czegoś takiego df_new = pd.concat([df1, df2], axis=1), ignore_index=Falsedomyślnie zaznaczając to .
Alexander
51

Wygląda na to, że w najnowszych wersjach Pandas można użyć df.assign :

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

Nie produkuje SettingWithCopyWarning.

Michaił Korobow
źródło
1
Kopiowanie komentarza @smci z góry ... Zamiast mówić „obecnie” lub odwoływać się do lat, proszę odnieść się do numerów wersji Pandy
Kyle C
50

Wykonanie tego bezpośrednio przez NumPy będzie najbardziej wydajne:

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

Zwróć uwagę, że moją pierwotną (bardzo starą) sugestią było użycie map(która jest znacznie wolniejsza):

df1['e'] = df1['a'].map(lambda x: np.random.random())
Andy Hayden
źródło
1
dziękuję za odpowiedź, jak już dałem, czy mogę zmodyfikować kod, .mapaby użyć istniejącej serii zamiast lambda? Staram df1['e'] = df1['a'].map(lambda x: e)albo df1['e'] = df1['a'].map(e)ale to nie to, czego potrzebują. (Jestem nowy w pyhon i twoja poprzednia odpowiedź już mi pomogła)
tomasz74,
@ tomasz74, jeśli masz już eSerię, to nie musisz jej używać map, użyj df['e']=e(odpowiedź @joaquins).
Andy Hayden,
49

Super proste przypisanie kolumny

Ramka danych pandy jest implementowana jako uporządkowany zrzut kolumn.

Oznacza to, że __getitem__ []można użyć nie tylko do uzyskania określonej kolumny, ale również__setitem__ [] = można też przypisać nową kolumnę.

Na przykład do tej ramki danych można dodać kolumnę, używając po prostu []akcesorium

    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

Pamiętaj, że działa to nawet wtedy, gdy indeks ramki danych jest wyłączony.

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

[] = droga do zrobienia, ale uważaj!

Jeśli jednak masz pd.Seriesi spróbuj przypisać go do ramki danych, w której indeksy są wyłączone, napotkasz problemy. Zobacz przykład:

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

Wynika to z faktu, że pd.Seriesdomyślnie indeks jest wyliczany od 0 do n. A [] =metoda pand stara się być „inteligentna”

Co się właściwie dzieje?

Podczas korzystania z [] =metody pandy cicho wykonują zewnętrzne połączenie lub scalanie zewnętrzne przy użyciu indeksu lewej ramki danych i indeksu prawej serii.df['column'] = series

Dygresja

To szybko powoduje dysonans poznawczy, ponieważ []=metoda stara się robić wiele różnych rzeczy w zależności od danych wejściowych, a wyniku nie można przewidzieć, chyba że wiesz, jak działają pandy. Dlatego odradzałbym []=podstawy kodu, ale podczas eksploracji danych w notatniku jest w porządku.

Obejście problemu

Jeśli masz pd.Series i chcesz przypisać go od góry do dołu lub jeśli kodujesz kod produkcyjny i nie masz pewności co do kolejności indeksowania, warto zabezpieczyć się przed tego rodzaju problemami.

Możesz obniżyć pd.Seriesdo a np.ndarraylub a list, to załatwi sprawę.

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

lub

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

Ale to nie jest bardzo jednoznaczne.

Może przyjdzie jakiś koder i powie „Hej, to wygląda na zbędne, po prostu zoptymalizuję to”.

Wyraźny sposób

Ustawienie indeksu pd.Seriesna indeks indeksu dfjest jawne.

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

Lub bardziej realistycznie, prawdopodobnie masz pd.Seriesjuż dostępny.

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

3     no
2     no
1     no
0    yes

Można teraz przypisać

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

Alternatywny sposób z df.reset_index()

Ponieważ dysonans indeksu jest problemem, jeśli uważasz, że indeks ramki danych nie powinien dyktować rzeczy, możesz po prostu upuścić indeks, powinno to być szybsze, ale nie jest bardzo czyste, ponieważ Twoja funkcja prawdopodobnie wykonuje teraz dwie rzeczy.

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

Uwaga na df.assign

Choć df.assignstał się bardziej wyraźny, co robisz, to faktycznie ma te same problemy jak wyżej[]=

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

Uważaj tylko, df.assignaby twoja kolumna nie została wywołana self. Spowoduje to błędy. To df.assign śmierdzi , ponieważ w funkcji znajdują się tego rodzaju artefakty.

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

Możesz powiedzieć: „No cóż, wtedy po prostu nie selfużyję”. Ale kto wie, jak ta funkcja zmieni się w przyszłości, aby wspierać nowe argumenty. Być może nazwa kolumny będzie argumentem w nowej aktualizacji pand, powodując problemy z aktualizacją.

firelynx
źródło
6
Gdy używasz [] =metody, pandy cicho wykonują łączenie zewnętrzne lub scalanie zewnętrzne ”. To najważniejsza informacja w całym temacie. Ale czy możesz podać link do oficjalnej dokumentacji dotyczącej działania []=operatora?
Lightman
25

Najłatwiejsze sposoby:

data['new_col'] = list_of_values

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

W ten sposób unikasz tak zwanego indeksowania łańcuchowego, ustawiając nowe wartości w obiekcie pandy. Kliknij tutaj, aby przeczytać dalej .

Abhishek
źródło
23

Jeśli chcesz ustawić całą nową kolumnę na początkową wartość podstawową (np. None), Możesz to zrobić:df1['e'] = None

To faktycznie przypisałoby komórce typ „obiektu”. Później możesz swobodnie umieszczać złożone typy danych, takie jak lista, w poszczególnych komórkach.

digdug
źródło
1
podnosi to ustawienie withcopywarning
00__00__00
1
df ['E'] = '' działa również, jeśli ktoś chce dodać pustą kolumnę
debaonline4u
21

Mam bał SettingWithCopyWarningi nie została ustalona za pomocą składni iloc. Mój DataFrame został utworzony przez read_sql ze źródła ODBC. Korzystając z sugestii Lowtech powyżej, następujące działania działały dla mnie:

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

To działało dobrze, aby wstawić kolumnę na końcu. Nie wiem, czy jest to najbardziej wydajny, ale nie lubię komunikatów ostrzegawczych. Myślę, że istnieje lepsze rozwiązanie, ale nie mogę go znaleźć i myślę, że zależy to od jakiegoś aspektu indeksu.
Uwaga . To działa tylko raz i wyświetli komunikat o błędzie przy próbie zastąpienia istniejącej kolumny.
Uwaga Jak wyżej i od 0.16.0 przypisanie jest najlepszym rozwiązaniem. Zobacz dokumentację http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Działa dobrze dla typu przepływu danych, w którym nie zastępuje się wartości pośrednich.

hum3
źródło
To jedyny sposób, który działa dla mnie w 2019 roku!
hydradon
14
  1. Najpierw utwórz pytona, list_of_ektóry ma odpowiednie dane.
  2. Użyj tego: df['e'] = list_of_e
Sumit Pokhrel
źródło
1
Naprawdę nie rozumiem, dlaczego nie jest to preferowana odpowiedź. Jeśli masz pd.Series, tolist()polecenie może być pomocne.
Więc S
11

Jeśli kolumna, którą próbujesz dodać, jest zmienną serii, po prostu:

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

Działa to dobrze, nawet jeśli zastępujesz istniejącą kolumnę. Po prostu wpisz nową nazwę_kolumny taką samą jak kolumna, którą chcesz zastąpić. Po prostu zastąpi istniejące dane kolumny nowymi danymi serii.

Akshay Singhvi
źródło
10

Jeśli ramka danych i obiekt serii mają ten sam indeks , pandas.concatdziała również tutaj:

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

W przypadku, gdy nie mają tego samego indeksu:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)
Psidom
źródło
10

Niezawodny:

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

Przykład:

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
źródło
2
Niezawodny. Nie dotyczy to pytania PO, które ma miejsce w przypadku, gdy wskaźniki istniejącej ramki danych i nowej serii nie są wyrównane.
Alexander
7

Dodam tylko, że podobnie jak w przypadku hum3 , .locnie rozwiązałem problemu SettingWithCopyWarningi musiałem się do niego odwołaćdf.insert() . W moim przypadku fałszywie dodatni został wygenerowany przez „fałszywe” indeksowanie łańcucha dict['a']['e'], gdzie 'e'jest nowa kolumna i dict['a']jest to DataFrame pochodząca ze słownika.

Pamiętaj również, że jeśli wiesz, co robisz, możesz przełączyć ostrzeżenie za pomocą pd.options.mode.chained_assignment = None i niż użyć jednego z innych podanych tutaj rozwiązań.

kkumer
źródło
7

aby wstawić nową kolumnę w danym miejscu (0 <= loc <= ilość kolumn) w ramce danych, wystarczy użyć Dataframe.insert:

DataFrame.insert(loc, column, value)

Dlatego jeśli chcesz dodać kolumnę e na końcu ramki danych o nazwie df , możesz użyć:

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

wartość może być Serią, liczbą całkowitą (w którym to przypadku wszystkie komórki zostaną wypełnione tą jedną wartością) lub strukturą podobną do tablicy

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

Nooyi
źródło
6

Przed przypisaniem nowej kolumny, jeśli indeksowałeś dane, musisz posortować indeks. Przynajmniej w moim przypadku musiałem:

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
źródło
6

Należy jednak zauważyć, że jeśli to zrobisz

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

będzie to skutecznie lewy łącznik w pliku df1.index. Więc jeśli chcesz uzyskać efekt łączenia zewnętrznego , moim prawdopodobnie niedoskonałym rozwiązaniem jest utworzenie ramki danych z wartościami indeksu obejmującymi wszechświat twoich danych, a następnie użyć powyższego kodu. Na przykład,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)
WillZ
źródło
5

Szukałem ogólnego sposobu dodawania kolumny numpy.nans do ramki danych bez głupotySettingWithCopyWarning .

Z następujących czynności:

  • odpowiedzi tutaj
  • to pytanie dotyczące przekazywania zmiennej jako argumentu słowa kluczowego
  • ta metoda generowania numpymacierzy NaN w linii

Wymyśliłem to:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})
ryanjdillon
źródło
4

Aby dodać nową kolumnę „e” do istniejącej ramki danych

 df1.loc[:,'e'] = Series(np.random.randn(sLength))
Chirag
źródło
Daje także komunikat o zastrzeżeniu
B Furtado
powinieneś użyć df1.loc [::, 'e'] = Series (np.random.randn (sLength))
Hermes Morales
4

Ze względu na kompletność - kolejne rozwiązanie wykorzystujące metodę DataFrame.eval () :

Dane:

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

Rozwiązanie:

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
źródło
4

Aby utworzyć pustą kolumnę

df['i'] = None
JNZ
źródło
3

Oto co zrobiłem ... Ale jestem całkiem nowy w pandach i ogólnie w Pythonie, więc nie obiecuję.

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
źródło
3

Jeśli się SettingWithCopyWarningpojawi, łatwym rozwiązaniem jest skopiowanie ramki danych, do której próbujesz dodać kolumnę.

df = df.copy()
df['col_name'] = values
Fredcallaway
źródło
10
to nie jest dobry pomysł. Jeśli ramka danych jest wystarczająco duża, będzie wymagała dużej ilości pamięci ... Poza tym zamieniłaby się w koszmar, jeśli od czasu do czasu dodajesz kolumny.
Kevad