Biorąc pod uwagę ramkę DataFrame:
np.random.seed(0)
df = pd.DataFrame(np.random.randn(3, 3), columns=list('ABC'), index=[1, 2, 3])
df
A B C
1 1.764052 0.400157 0.978738
2 2.240893 1.867558 -0.977278
3 0.950088 -0.151357 -0.103219
Jaki jest najprostszy sposób dodania nowej kolumny zawierającej stałą wartość, np. 0?
A B C new
1 1.764052 0.400157 0.978738 0
2 2.240893 1.867558 -0.977278 0
3 0.950088 -0.151357 -0.103219 0
To jest moje rozwiązanie, ale nie wiem, dlaczego powoduje to umieszczenie NaN w „nowej” kolumnie?
df['new'] = pd.Series([0 for x in range(len(df.index))])
A B C new
1 1.764052 0.400157 0.978738 0.0
2 2.240893 1.867558 -0.977278 0.0
3 0.950088 -0.151357 -0.103219 NaN
df['new'] = pd.Series([0 for x in range(len(df.index))], index=df.index)
.[0] * len(df.index)
df['new'] = 0
Odpowiedzi:
Powodem, dla którego jest to umieszczane
NaN
w kolumnie, jest to, żedf.index
i obiekt poIndex
prawej stronie są różne. @zach pokazuje właściwy sposób przypisywania nowej kolumny zer. Ogólnie rzecz biorąc,pandas
stara się jak najbardziej wyrównywać indeksy. Jedną wadą jest to, że gdy indeksy nie są wyrównane, dostajesz sięNaN
tam, gdzie nie są wyrównane. Pobaw się z metodamireindex
ialign
, aby uzyskać intuicję dotyczącą wyrównywania, które działa z obiektami, które mają częściowo, całkowicie i nie wyrównane-wszystkie wyrównane indeksy. Na przykład oto jakDataFrame.align()
działa z częściowo wyrównanymi indeksami:In [7]: from pandas import DataFrame In [8]: from numpy.random import randint In [9]: df = DataFrame({'a': randint(3, size=10)}) In [10]: In [10]: df Out[10]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [11]: s = df.a[:5] In [12]: dfa, sa = df.align(s, axis=0) In [13]: dfa Out[13]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [14]: sa Out[14]: 0 0 1 2 2 0 3 1 4 0 5 NaN 6 NaN 7 NaN 8 NaN 9 NaN Name: a, dtype: float64
źródło
Super proste przypisanie na miejscu:
df['new'] = 0
W przypadku modyfikacji w miejscu wykonaj bezpośrednie przypisanie. To zadanie jest nadawane przez pandy dla każdego rzędu.
df = pd.DataFrame('x', index=range(4), columns=list('ABC')) df A B C 0 x x x 1 x x x 2 x x x 3 x x x
df['new'] = 'y' # Same as, # df.loc[:, 'new'] = 'y' df A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x y
Uwaga dotycząca kolumn obiektów
Jeśli chcesz dodać kolumnę pustych list, oto moja rada:
object
kolumny to zła wiadomość pod względem wydajności. Przemyśl strukturę swoich danych.Jeśli musisz przechowywać kolumnę list, nie kopiuj wielokrotnie tego samego odniesienia.
# Wrong df['new'] = [[]] * len(df) # Right df['new'] = [[] for _ in range(len(df))]
Generowanie kopii:
df.assign(new=0)
Jeśli zamiast tego potrzebujesz kopii, użyj
DataFrame.assign
:df.assign(new='y') A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x y
A jeśli chcesz przypisać wiele takich kolumn o tej samej wartości, jest to tak proste, jak:
c = ['new1', 'new2', ...] df.assign(**dict.fromkeys(c, 'y')) A B C new1 new2 0 x x x y y 1 x x x y y 2 x x x y y 3 x x x y y
Przypisanie wielu kolumn
Wreszcie, jeśli chcesz przypisać wiele kolumn z różnymi wartościami, możesz użyć
assign
słownika.c = {'new1': 'w', 'new2': 'y', 'new3': 'z'} df.assign(**c) A B C new1 new2 new3 0 x x x w y z 1 x x x w y z 2 x x x w y z 3 x x x w y z
źródło
Dzięki nowoczesnym pandom możesz po prostu:
df['new'] = 0
źródło
Oto kolejna linijka używająca lambd (utwórz kolumnę o stałej wartości = 10)
df['newCol'] = df.apply(lambda x: 10, axis=1)
przed
df A B C 1 1.764052 0.400157 0.978738 2 2.240893 1.867558 -0.977278 3 0.950088 -0.151357 -0.103219
po
df A B C newCol 1 1.764052 0.400157 0.978738 10 2 2.240893 1.867558 -0.977278 10 3 0.950088 -0.151357 -0.103219 10
źródło
df['newCol'] = 10
jest również jednym wkładem (i jest szybszy). Jaka jest zaleta korzystania z aplikacji Apply tutaj?df['new'] = [[] for _ in range(len(df))]