我有3个CSV文件。每个数据框架的第一列都是人的(字符串)名,而每个数据框架中的所有其他列都是人的属性。
我如何将所有三个CSV文档“联接”在一起,以创建一个单一的CSV,其中每行都具有人的字符串名称的每个唯一值的所有属性?
pandas中的join()函数指定我需要一个多索引,但我对分层索引方案与基于单个索引进行连接有什么关系感到困惑。
我有3个CSV文件。每个数据框架的第一列都是人的(字符串)名,而每个数据框架中的所有其他列都是人的属性。
我如何将所有三个CSV文档“联接”在一起,以创建一个单一的CSV,其中每行都具有人的字符串名称的每个唯一值的所有属性?
pandas中的join()函数指定我需要一个多索引,但我对分层索引方案与基于单个索引进行连接有什么关系感到困惑。
当前回答
可以使用.join()函数将三者连接在一起。
假设你有三个数据框架 Df1 df2 df3。 要将这些数据加入到一个数据框架中,你可以:
df = df1.join(df2).join(df3)
这是我发现的完成这项任务最简单的方法。
其他回答
下面是一个合并数据帧字典的方法,同时保持列名与字典同步。如果需要,它还会填充缺失的值:
这是合并数据帧字典的函数
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)
对于一个数据帧列表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')
我调整了接受的答案,使用reduce对不同后缀参数上的多个数据帧执行操作,我猜它也可以扩展到不同的参数上。
from functools import reduce
dfs_with_suffixes = [(df2,suffix2), (df3,suffix3),
(df4,suffix4)]
merge_one = lambda x,y,sfx:pd.merge(x,y,on=['col1','col2'..], suffixes=sfx)
merged = reduce(lambda left,right:merge_one(left,*right), dfs_with_suffixes, df1)
简单的解决方案:
如果列名相似:
df1.merge(df2,on='col_name').merge(df3,on='col_name')
如果列名不同:
df1.merge(df2,left_on='col_name1', right_on='col_name2').merge(df3,left_on='col_name1', right_on='col_name3').drop(columns=['col_name2', 'col_name3']).rename(columns={'col_name1':'col_name'})
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],
['d', 14, 16]]
),
columns=['name', 'attr21', 'attr22']
)
df3 = pd.DataFrame(np.array([
['a', 15, 49],
['c', 4, 36],
['d', 14, 9]]),
columns=['name', 'attr31', 'attr32']
)
df4 = pd.DataFrame(np.array([
['a', 15, 49],
['c', 4, 36],
['c', 14, 9]]),
columns=['name', 'attr41', 'attr42']
)
加入列表数据框架的三种方法
pandas.concat
dfs = [df1, df2, df3]
dfs = [df.set_index('name') for df in dfs]
# cant not run if index not unique
dfs = pd.concat(dfs, join='outer', axis = 1)
functools.reduce
dfs = [df1, df2, df3, df4]
# still run with index not unique
import functools as ft
df_final = ft.reduce(lambda left, right: pd.merge(left, right, on='name', how = 'outer'), dfs)
加入
# cant not run if index not unique
dfs = [df1, df2, df3]
dfs = [df.set_index('name') for df in dfs]
dfs[0].join(dfs[1:], how = 'outer')