CSV 파일이 3 개 있습니다. 각각은 사람의 (문자열) 이름으로 첫 번째 열을 갖는 반면, 각 데이터 프레임의 다른 모든 열은 해당 개인의 속성입니다.
세 개의 CSV 문서를 모두 “결합”하여 각 행에 개인 문자열 이름의 각 고유 값에 대한 모든 속성이있는 단일 CSV를 만들려면 어떻게해야합니까?
join()
pandas 의 함수는 다중 인덱스가 필요하다는 것을 지정하지만 단일 인덱스를 기반으로 조인을 만드는 것과 계층 적 인덱싱 체계가 무엇을 해야하는지 혼란 스럽습니다.
답변
가정 수입 :
import pandas as pd
John Galt의 대답 은 기본적으로 reduce
작업입니다. 소수의 데이터 프레임이있는 경우 다음과 같은 목록에 추가합니다 (목록 이해 또는 루프 또는 기타를 통해 생성됨).
dfs = [df0, df1, df2, dfN]
name
예 와 같이 공통 열이 있다고 가정하면 다음을 수행합니다.
df_final = reduce(lambda left,right: pd.merge(left,right,on='name'), dfs)
이런 식으로 코드는 병합하려는 데이터 프레임 수에 관계없이 작동해야합니다.
2016 년 8 월 1 일 수정 : Python 3을 사용하는 사람들 reduce
은로 이동했습니다 functools
. 따라서이 기능을 사용하려면 먼저 해당 모듈을 가져와야합니다.
from functools import reduce
답변
3 개의 데이터 프레임이 있으면 시도해 볼 수 있습니다
# Merge multiple dataframes
df1 = pd.DataFrame(np.array([
['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr11', 'attr12'])
df2 = pd.DataFrame(np.array([
['a', 5, 19],
['b', 14, 16],
['c', 4, 9]]),
columns=['name', 'attr21', 'attr22'])
df3 = pd.DataFrame(np.array([
['a', 15, 49],
['b', 4, 36],
['c', 14, 9]]),
columns=['name', 'attr31', 'attr32'])
pd.merge(pd.merge(df1,df2,on='name'),df3,on='name')
또는 cwharland가 언급 한 바와 같이
df1.merge(df2,on='name').merge(df3,on='name')
답변
이 join
방법 의 이상적인 상황입니다
이 join
방법은 이러한 유형의 상황에 맞게 작성되었습니다. 원하는 수의 DataFrame을 함께 결합 할 수 있습니다. 호출하는 DataFrame은 전달 된 DataFrame 컬렉션의 인덱스와 결합됩니다. 여러 DataFrame을 사용하려면 조인 열을 인덱스에 넣어야합니다.
코드는 다음과 같습니다.
filenames = ['fn1', 'fn2', 'fn3', 'fn4',....]
dfs = [pd.read_csv(filename, index_col=index_col) for filename in filenames)]
dfs[0].join(dfs[1:])
@zero의 데이터를 사용하면 다음과 같이 할 수 있습니다.
df1 = pd.DataFrame(np.array([
['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr11', 'attr12'])
df2 = pd.DataFrame(np.array([
['a', 5, 19],
['b', 14, 16],
['c', 4, 9]]),
columns=['name', 'attr21', 'attr22'])
df3 = pd.DataFrame(np.array([
['a', 15, 49],
['b', 4, 36],
['c', 14, 9]]),
columns=['name', 'attr31', 'attr32'])
dfs = [df1, df2, df3]
dfs = [df.set_index('name') for df in dfs]
dfs[0].join(dfs[1:])
attr11 attr12 attr21 attr22 attr31 attr32
name
a 5 9 5 19 15 49
b 4 61 14 16 4 36
c 24 9 4 9 14 9
답변
데이터 프레임 목록에 대해 다음과 같이 수행 할 수도 있습니다 df_list
.
df = df_list[0]
for df_ in df_list[1:]:
df = df.merge(df_, on='join_col_name')
또는 데이터 프레임이 생성기 객체에있는 경우 (예 : 메모리 소비를 줄이기 위해) :
df = next(df_list)
for df_ in df_list:
df = df.merge(df_, on='join_col_name')
답변
0.22.0의 python
3.6.3 에서는 결합에 사용하려는 열을 색인으로 설정 pandas
하는 한 사용할 수도 있습니다.concat
pd.concat(
(iDF.set_index('name') for iDF in [df1, df2, df3]),
axis=1, join='inner'
).reset_index()
어디에서 df1
, df2
그리고 df3
같이 정의된다 존 갈트의 대답
import pandas as pd
df1 = pd.DataFrame(np.array([
['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr11', 'attr12']
)
df2 = pd.DataFrame(np.array([
['a', 5, 19],
['b', 14, 16],
['c', 4, 9]]),
columns=['name', 'attr21', 'attr22']
)
df3 = pd.DataFrame(np.array([
['a', 15, 49],
['b', 4, 36],
['c', 14, 9]]),
columns=['name', 'attr31', 'attr32']
)
답변
조인 작업 을 수행하기 위해 다중 인덱스가 필요하지 않습니다 . 조인 작업을 수행 할 인덱스 열을 올바르게 설정하면됩니다 ( df.set_index('Name')
예 : 명령 )
join
작업은 인덱스에서 수행 기본입니다. 귀하의 경우, Name
열이 색인과 일치하도록 지정해야합니다 . 아래는 예입니다
튜토리얼 유용 할 수 있습니다.
# Simple example where dataframes index are the name on which to perform the join operations
import pandas as pd
import numpy as np
name = ['Sophia' ,'Emma' ,'Isabella' ,'Olivia' ,'Ava' ,'Emily' ,'Abigail' ,'Mia']
df1 = pd.DataFrame(np.random.randn(8, 3), columns=['A','B','C'], index=name)
df2 = pd.DataFrame(np.random.randn(8, 1), columns=['D'], index=name)
df3 = pd.DataFrame(np.random.randn(8, 2), columns=['E','F'], index=name)
df = df1.join(df2)
df = df.join(df3)
# If you a 'Name' column that is not the index of your dataframe, one can set this column to be the index
# 1) Create a column 'Name' based on the previous index
df1['Name']=df1.index
# 1) Select the index from column 'Name'
df1=df1.set_index('Name')
# If indexes are different, one may have to play with parameter how
gf1 = pd.DataFrame(np.random.randn(8, 3), columns=['A','B','C'], index=range(8))
gf2 = pd.DataFrame(np.random.randn(8, 1), columns=['D'], index=range(2,10))
gf3 = pd.DataFrame(np.random.randn(8, 2), columns=['E','F'], index=range(4,12))
gf = gf1.join(gf2, how='outer')
gf = gf.join(gf3, how='outer')
답변
다음은 열 이름을 사전과 동기화하면서 데이터 프레임 사전을 병합하는 방법입니다. 또한 필요한 경우 결 측값을 채 웁니다.
이것은 데이터 프레임의 사전을 병합하는 기능입니다
def MergeDfDict(dfDict, onCols, how='outer', naFill=None):
keys = dfDict.keys()
for i in range(len(keys)):
key = keys[i]
df0 = dfDict[key]
cols = list(df0.columns)
valueCols = list(filter(lambda x: x not in (onCols), cols))
df0 = df0[onCols + valueCols]
df0.columns = onCols + [(s + '_' + key) for s in valueCols]
if (i == 0):
outDf = df0
else:
outDf = pd.merge(outDf, df0, how=how, on=onCols)
if (naFill != None):
outDf = outDf.fillna(naFill)
return(outDf)
좋아, 데이터를 생성하고 이것을 테스트하자 :
def GenDf(size):
df = pd.DataFrame({'categ1':np.random.choice(a=['a', 'b', 'c', 'd', 'e'], size=size, replace=True),
'categ2':np.random.choice(a=['A', 'B'], size=size, replace=True),
'col1':np.random.uniform(low=0.0, high=100.0, size=size),
'col2':np.random.uniform(low=0.0, high=100.0, size=size)
})
df = df.sort_values(['categ2', 'categ1', 'col1', 'col2'])
return(df)
size = 5
dfDict = {'US':GenDf(size), 'IN':GenDf(size), 'GER':GenDf(size)}
MergeDfDict(dfDict=dfDict, onCols=['categ1', 'categ2'], how='outer', naFill=0)