Series와 DataFrame을 병합하는 방법


82

당신에 대한 정보를 찾고 여기 온 경우 을 병합하는 방법 DataFrameSeries인덱스에 , 봐주세요 이 답변 .

OP의 원래 의도는 시리즈 요소를 다른 DataFrame에 열로 할당하는 방법을 묻는 것이 었 습니다 . 이것에 대한 답을 알고 싶다면 EdChum 이 받아 들인 대답 을보십시오.


내가 생각 해낼 수있는 최선은

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

누구든지 더 나은 구문 / 빠른 방법을 제안 할 수 있습니까?

내 시도 :

df.merge(s)
AttributeError: 'Series' object has no attribute 'columns'

df.join(s)
ValueError: Other Series must have a name

편집 게시 된 처음 두 개의 답변은 내 질문에 대한 문제를 강조 했으므로 다음을 사용하여 구성하십시오 df.

df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])

최종 결과로

    a  b  s1  s2
3 NaN  4   5   6
5   2  5   5   6
6   3  6   5   6

답변:


25

시리즈에서 데이터 프레임을 생성 한 다음 데이터 프레임과 병합 할 수 있습니다. 따라서 데이터를 값으로 지정하지만 길이를 곱하고 열을 인덱스로 설정하고 left_index 및 right_index에 대한 매개 변수를 True로 설정합니다.

In [27]:

df.merge(pd.DataFrame(data = [s.values] * len(s), columns = s.index), left_index=True, right_index=True)
Out[27]:
   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

시리즈에서 생성 된 df의 색인이 df의 색인을 사용하기를 원하는 상황에 대해 편집 한 다음 다음을 수행 할 수 있습니다.

df.merge(pd.DataFrame(data = [s.values] * len(df), columns = s.index, index=df.index), left_index=True, right_index=True)

이것은 인덱스가 길이와 일치한다고 가정합니다.


163

업데이트
v0.24.0부터 Series 이름이 지정된 경우 DataFrame 및 Series에서 병합 할 수 있습니다.

df.merge(s.rename('new'), left_index=True, right_index=True)
# If series is already named,
# df.merge(s, left_index=True, right_index=True)

요즘에는 to_frame ()을 사용하여 Series를 DataFrame으로 간단히 변환 할 수 있습니다 . 따라서 (인덱스에 가입하는 경우) :

df.merge(s.to_frame(), left_index=True, right_index=True)

5
질문의 dfand 의 정의를 사용하면 s이 답변 은 질문에서 요청한 결과가 아닌 빈 데이터 프레임을 반환합니다 . 우리는 색인에서 일치하고 싶지 않습니다. 의 s모든 행에 값 을 브로드 캐스트하려고합니다 df.
CPBL

2
이것은 다른 문제를 해결하는 것입니다 : "데이터 프레임과 시리즈가 주어 졌을 때, 그것들이 인덱스에서 어떻게 병합 될 수 있는가". OP의 질문은 "시리즈의 각 요소를 DataFrame의 새 열로 할당"이었습니다.
cs95

5

한 가지 방법은 다음과 같습니다.

df.join(pd.DataFrame(s).T).fillna(method='ffill')

여기서 일어나는 일을 분석하려면 ...

pd.DataFrame(s).Ts다음과 같은 1 행 DataFrame을 만듭니다 .

   s1  s2
0   5   6

다음 join으로이 새 프레임을 다음으로 연결합니다 df.

   a  b  s1  s2
0  1  3   5   6
1  2  4 NaN NaN

마지막으로 NaN인덱스 1 의 값 fillna은 forward-fill ( ffill) 인수를 사용하여 열의 이전 값 으로 채워집니다 .

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

를 사용하지 않으려면 에서 생성 된 DataFrame의 행을 반복하는 fillna데 사용할 pd.concat수 있습니다 s. 이 경우 일반적인 솔루션은 다음과 같습니다.

df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True))

다음은 편집 된 질문에서 제기 된 인덱싱 문제를 해결하기위한 또 다른 솔루션입니다.

df.join(pd.DataFrame(s.repeat(len(df)).values.reshape((len(df), -1), order='F'), 
        columns=s.index, 
        index=df.index))

s값을 반복하고 모양을 변경 ( 'Fortran'순서 지정)하고 적절한 열 이름과 인덱스를 전달하여 DataFrame으로 변환됩니다. 이 새 DataFrame은 df.


좋은 한 줄짜리,주의 할 점은 이미 df에있는 NaN도 채워질 것이라는 것입니다.
Nathan Lloyd

@Nonth 감사하고 좋은 지적입니다. NaN값을 채우지 않는 대안을 포함하도록 편집했습니다 .
Alex Riley

EdChums 원래 답변에서 발생한 일이이 수정 된 답변에 영향을 미칩니다. 예를 들어 df를 구성하면 index=[3, 5]새 열에 명령 뒤에 nan이 포함됩니다.
Nathan Lloyd

@Nonth 다시 편집! 이제 새로운 요구 사항을 충족해야합니다.
Alex Riley

귀하의 대답은 20 배 더 빠르지 만 1e5 행에서 df와 함께 ~ 100ms의 차이입니다. 내 for 루프가 끔찍하게 느립니다. 귀하의 답변에서 BTW는 일반적으로 적용 가능 2해야합니다 len(df).
Nathan Lloyd

0

다음과 같이 데이터 프레임을 설정하는 것이 좋습니다 (자동 인덱싱).

df = pd.DataFrame({'a':[np.nan, 1, 2], 'b':[4, 5, 6]})

그런 다음 s1 및 s2 값을 설정할 수 있습니다 (shape ()를 사용하여 df에서 행 수를 반환).

s = pd.DataFrame({'s1':[5]*df.shape[0], 's2':[6]*df.shape[0]})

원하는 결과는 쉽습니다.

display (df.merge(s, left_index=True, right_index=True))

또는 데이터 프레임 df에 새 값을 추가하십시오.

df = pd.DataFrame({'a':[nan, 1, 2], 'b':[4, 5, 6]})
df['s1']=5
df['s2']=6
display(df)

둘 다 반환 :

     a  b  s1  s2
0  NaN  4   5   6
1  1.0  5   5   6
2  2.0  6   5   6

(적용 할 단일 값 대신) 다른 데이터 목록이 있고 그 목록이 df와 동일한 순서임을 알고있는 경우, 예 :

s1=['a','b','c']

그런 다음 동일한 방법으로 연결할 수 있습니다.

df['s1']=s1

보고:

     a  b s1
0  NaN  4  a
1  1.0  5  b
2  2.0  6  c

0

pandas.DataFrame 열을 상수로 쉽게 설정할 수 있습니다. 이 상수는 예제와 같이 int가 될 수 있습니다. 지정한 열이 df에없는 경우 pandas는 지정한 이름으로 새 열을 만듭니다. 따라서 데이터 프레임이 구성된 후 (귀하의 질문에서) :

df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])

다음을 실행할 수 있습니다.

df['s1'], df['s2'] = 5, 6

실제 데이터를 저장하는 방법에 따라 튜플 목록의 모든 요소 또는 사전의 키와 값에 대해이 작업을 수행하도록 루프 또는 이해를 작성할 수 있습니다.


0

경우 df인은 pandas.DataFrame다음 df['new_col']= Series list_object of length len(df)라는 칼럼으로 또는 시리즈 list_object을 추가합니다 'new_col'. df['new_col']= scalar(예 : 귀하의 경우 5 또는 6)도 작동하며 다음과 같습니다.df['new_col']= [scalar]*len(df)

따라서 두 줄 코드가 목적에 부합합니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.