Jeśli przyszedłeś tutaj, szukając informacji na temat łączenia znaków
DataFrame
iSeries
w indeksie , spójrz na tę odpowiedź .Pierwotnym zamiarem PO było zapytanie, jak przypisać elementy serii jako kolumny do innej ramki DataFrame . Jeśli chcesz poznać odpowiedź na to pytanie, spójrz na odpowiedź zaakceptowaną przez EdChum.
Najlepsze, co mogę wymyślić, to
df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]}) # see EDIT below
s = pd.Series({'s1':5, 's2':6})
for name in s.index:
df[name] = s[name]
a b s1 s2
0 1 3 5 6
1 2 4 5 6
Czy ktoś może zaproponować lepszą składnię / szybszą metodę?
Moje próby:
df.merge(s)
AttributeError: 'Series' object has no attribute 'columns'
i
df.join(s)
ValueError: Other Series must have a name
EDYTUJ Pierwsze dwie opublikowane odpowiedzi zwróciły uwagę na problem z moim pytaniem, więc do skonstruowania użyj poniższego df
:
df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])
z końcowym wynikiem
a b s1 s2
3 NaN 4 5 6
5 2 5 5 6
6 3 6 5 6
df
i w pytanius
, ta odpowiedź zwraca mi pustą ramkę danych, a nie wynik żądany w pytaniu. Nie chcemy dopasowywać się do indeksu; chcemy rozgłaszaćs
wartości do wszystkich wierszydf
.Oto jeden sposób:
df.join(pd.DataFrame(s).T).fillna(method='ffill')
Aby wyjaśnić, co się tutaj dzieje ...
pd.DataFrame(s).T
tworzy jednowierszową ramkę DataFrame, zs
której wygląda następująco:s1 s2 0 5 6
Następnie
join
łączy tę nową ramkę zdf
:a b s1 s2 0 1 3 5 6 1 2 4 NaN NaN
Na koniec
NaN
wartości pod indeksem 1 są wypełniane poprzednimi wartościami w kolumnie przy użyciu argumentufillna
forward-fill (ffill
):a b s1 s2 0 1 3 5 6 1 2 4 5 6
Aby uniknąć używania
fillna
, można użyćpd.concat
do powtórzenia wierszy DataFrame skonstruowanych zs
. W tym przypadku ogólnym rozwiązaniem jest:df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True))
Oto kolejne rozwiązanie problemu z indeksowaniem przedstawionego w edytowanym pytaniu:
df.join(pd.DataFrame(s.repeat(len(df)).values.reshape((len(df), -1), order='F'), columns=s.index, index=df.index))
s
jest przekształcany w DataFrame przez powtórzenie wartości i zmianę kształtu (określenie kolejności „Fortran”), a także przekazanie odpowiednich nazw kolumn i indeksu. Ta nowa ramka DataFrame jest następnie dołączana dodf
.źródło
NaN
wartości.index=[3, 5]
nowe kolumny będą zawierać nan po twoim poleceniu.2
powinnolen(df)
mieć zastosowanie ogólne.Gdybym mógł zasugerować skonfigurowanie ramek danych w ten sposób (automatyczne indeksowanie):
df = pd.DataFrame({'a':[np.nan, 1, 2], 'b':[4, 5, 6]})
następnie możesz ustawić wartości s1 i s2 w ten sposób (używając shape (), aby zwrócić liczbę wierszy z df):
s = pd.DataFrame({'s1':[5]*df.shape[0], 's2':[6]*df.shape[0]})
wtedy wynik, który chcesz, jest łatwy:
display (df.merge(s, left_index=True, right_index=True))
Alternatywnie, po prostu dodaj nowe wartości do swojej ramki danych df:
df = pd.DataFrame({'a':[nan, 1, 2], 'b':[4, 5, 6]}) df['s1']=5 df['s2']=6 display(df)
Obie wracają:
a b s1 s2 0 NaN 4 5 6 1 1.0 5 5 6 2 2.0 6 5 6
Jeśli masz inną listę danych (zamiast pojedynczej wartości do zastosowania) i wiesz, że jest ona w tej samej kolejności co df, np:
s1=['a','b','c']
możesz to załączyć w ten sam sposób:
df['s1']=s1
zwroty:
a b s1 0 NaN 4 a 1 1.0 5 b 2 2.0 6 c
źródło
Możesz łatwo ustawić kolumnę pandas.DataFrame na stałą. Ta stała może być wartością typu int, taką jak w Twoim przykładzie. Jeśli określonej kolumny nie ma w pliku df, pandy utworzą nową kolumnę o podanej nazwie. Po skonstruowaniu ramki danych (z pytania):
df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])
Możesz po prostu biegać:
df['s1'], df['s2'] = 5, 6
Możesz napisać pętlę lub wyrażenie, aby zrobić to dla wszystkich elementów na liście krotek lub kluczy i wartości w słowniku, w zależności od tego, jak przechowujesz swoje prawdziwe dane.
źródło
Jeśli
df
jest a,pandas.DataFrame
todf['new_col']= Series list_object of length len(df)
doda lub Series list_object jako kolumnę o nazwie'new_col'
.df['new_col']= scalar
(na przykład 5 lub 6 w twoim przypadku) również działa i jest równoważnedf['new_col']= [scalar]*len(df)
Tak więc dwuwierszowy kod służy temu celowi:
df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]}) s = pd.Series({'s1':5, 's2':6}) for x in s.index: df[x] = s[x] Output: a b s1 s2 0 1 3 5 6 1 2 4 5 6
źródło