我有多个这样的数据框-
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个数据集中的公共列。我正在寻找一种适用于多列的解决方案,而不必像我在SO上看到的那样指定公共列(因为实际数据帧很大)。
答案 0 :(得分:0)
reduce,intersection,filter和concat的组合可以帮助您解决用例:
DB::rollback()
如果列和列的内容相同,那么您可以跳过列表理解,而仅从一个数据帧中进行过滤:
DB::rollback()
如果列的内容不同,则串联并删除重复项:
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]
答案 1 :(得分:0)
您可以使用reduce
,将函数r_common
从左到右累积应用于dfs
的数据帧,以便将dfs
的列表简化为单个数据帧df_common
。 intersection
方法用于在d1
函数内部的两个数据帧d2
和r_common
中找出公共列。
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
答案 2 :(得分:0)
如果需要在每个DataFrame中具有相同内容的过滤器列名称,可以将其转换为元组并进行比较:
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)}