Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用多个公共列连接多个数据帧_Python_Python 3.x_Pandas - Fatal编程技术网

Python 使用多个公共列连接多个数据帧

Python 使用多个公共列连接多个数据帧,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有多个这样的数据帧- df=pd.DataFrame({'a':[1,2,3],'b':[3,4,5],'c':[4,6,7]}) df2=pd.DataFrame({'a':[1,2,3],'d':[66,24,55],'c':[4,6,7]}) df3=pd.DataFrame({'a':[1,2,3],'f':[31,74,95],'c':[4,6,7]}) 我想要这个输出- a c 0 1 4 1 2 6 2 3 7 这是3个数据集中的公共列。我

我有多个这样的数据帧-

df=pd.DataFrame({'a':[1,2,3],'b':[3,4,5],'c':[4,6,7]})
df2=pd.DataFrame({'a':[1,2,3],'d':[66,24,55],'c':[4,6,7]})
df3=pd.DataFrame({'a':[1,2,3],'f':[31,74,95],'c':[4,6,7]})
我想要这个输出-

    a   c
0   1   4
1   2   6
2   3   7
这是3个数据集中的公共列。我正在寻找一种解决方案,它可以适用于多个列,而不必像我在上面看到的那样指定公共列(因为实际的数据帧是巨大的)。

以下各项的组合可以帮助解决您的用例:

dfs = (df,df2,df3)
cols = [ent.columns for ent in dfs]
cols

[Index(['a', 'b', 'c'], dtype='object'),
 Index(['a', 'd', 'c'], dtype='object'),
 Index(['a', 'f', 'c'], dtype='object')]

#find the common columns to all : 
from functools import reduce
universal_cols = reduce(lambda x,y : x.intersection(y), cols).tolist()
universal_cols

['a', 'c']

#filter for only universal_cols for each df
updates = [ent.filter(universal_cols) for ent in dfs]
如果列和列的内容相同,则可以跳过列表理解,只从一个数据帧进行筛选:

#let's use the first dataframe
output = df.filter(universal_cols)
如果列的内容不同,则连接并删除重复项:

#concatenate and drop duplicates
res = pd.concat(updates).drop_duplicates()

res  #output has the same result

    a   c
0   1   4
1   2   6
2   3   7
和的组合有助于您的用例:

dfs = (df,df2,df3)
cols = [ent.columns for ent in dfs]
cols

[Index(['a', 'b', 'c'], dtype='object'),
 Index(['a', 'd', 'c'], dtype='object'),
 Index(['a', 'f', 'c'], dtype='object')]

#find the common columns to all : 
from functools import reduce
universal_cols = reduce(lambda x,y : x.intersection(y), cols).tolist()
universal_cols

['a', 'c']

#filter for only universal_cols for each df
updates = [ent.filter(universal_cols) for ent in dfs]
如果列和列的内容相同,则可以跳过列表理解,只从一个数据帧进行筛选:

#let's use the first dataframe
output = df.filter(universal_cols)
如果列的内容不同,则连接并删除重复项:

#concatenate and drop duplicates
res = pd.concat(updates).drop_duplicates()

res  #output has the same result

    a   c
0   1   4
1   2   6
2   3   7
您可以使用,将函数
r_common
从左到右累积应用于
dfs
的数据帧,以便将
dfs
列表减少为单个数据帧
df_common
。该方法用于在
r\u common
函数中查找两个数据帧
d1
d2
中的公共列

def r_common(d1, d2):
    cols = d1.columns.intersection(d2.columns).tolist()
    m =  d1[cols].eq(d2[cols]).all()
    return d1[m[m].index]

df_common = reduce(r_common, dfs) # dfs = [df, df2, df3]
结果:

# print(df_common)
   a  c
0  1  4
1  2  6
2  3  7
您可以使用,将函数
r_common
从左到右累积应用于
dfs
的数据帧,以便将
dfs
列表减少为单个数据帧
df_common
。该方法用于在
r\u common
函数中查找两个数据帧
d1
d2
中的公共列

def r_common(d1, d2):
    cols = d1.columns.intersection(d2.columns).tolist()
    m =  d1[cols].eq(d2[cols]).all()
    return d1[m[m].index]

df_common = reduce(r_common, dfs) # dfs = [df, df2, df3]
结果:

# print(df_common)
   a  c
0  1  4
1  2  6
2  3  7

如果需要,可以将每个数据帧中具有相同内容的筛选器列名称转换为元组并进行比较:

dfs = [df, df2, df3]  
df1 = pd.concat([x.apply(tuple) for x in dfs], axis=1)
cols = df1.index[df1.eq(df1.iloc[:, 0], axis=0).all(axis=1)]

df2 = df[cols]
print (df2) 
   a  c
0  1  4
1  2  6
2  3  7
如果列名称应不同且有必要仅比较内容:

df=pd.DataFrame({'a':[1,2,3],'b':[3,4,5],'c':[4,6,7]})
df2=pd.DataFrame({'r':[1,2,3],'t':[66,24,55],'l':[4,6,7]})
df3=pd.DataFrame({'f':[1,2,3],'g':[31,74,95],'m':[4,6,7]})

dfs = [df, df2, df3]  
p = [x.apply(tuple).tolist() for x in dfs]
a = set(p[0]).intersection(*p)
print (a) 
{(4, 6, 7), (1, 2, 3)}

如果需要,可以将每个数据帧中具有相同内容的筛选器列名称转换为元组并进行比较:

dfs = [df, df2, df3]  
df1 = pd.concat([x.apply(tuple) for x in dfs], axis=1)
cols = df1.index[df1.eq(df1.iloc[:, 0], axis=0).all(axis=1)]

df2 = df[cols]
print (df2) 
   a  c
0  1  4
1  2  6
2  3  7
如果列名称应不同且有必要仅比较内容:

df=pd.DataFrame({'a':[1,2,3],'b':[3,4,5],'c':[4,6,7]})
df2=pd.DataFrame({'r':[1,2,3],'t':[66,24,55],'l':[4,6,7]})
df3=pd.DataFrame({'f':[1,2,3],'g':[31,74,95],'m':[4,6,7]})

dfs = [df, df2, df3]  
p = [x.apply(tuple).tolist() for x in dfs]
a = set(p[0]).intersection(*p)
print (a) 
{(4, 6, 7), (1, 2, 3)}

你只想要普通列还是想要所有元素都相同的普通列?@ShubhamSharma with element你想要普通列还是想要所有元素都相同的普通列?@ShubhamSharma with element我作为empy获得最终df,即使我得到一个通用列列表,当你只在一个数据帧上选择时,你会得到什么?我是将最终df作为empy获取,即使我得到了一个通用列的列表当你只在一个数据帧上选择时,你会得到什么?我得到一个关键错误,表示列中没有列在那里。第二个解决方案不会返回带有列名的数据帧。它只打印elements@ubuntu_noob-有一件事,是否需要比较列名称和内容?或者只有内容和列名不像在第二个解决方案中那样重要?我收到一个关键错误,表示列中没有列在那里。第二个解决方案不返回带有列名的数据帧。它只打印elements@ubuntu_noob-一件事,您需要比较列名称和内容吗?或者只有内容和列名不像第二个解决方案那样重要?