2016-03-04 78 views
2

我是熊猫的新手,怀疑这有一个简单的答案,但它现在正在困扰着我。我想从多个数据框(具有相同列)中选择一行中的值出现在所有数据框中的行。通过多个熊猫数据框中的常见值进行选择

所以,如果我有以下几点:

import numpy as np 
import pandas as pd 

df1 = pd.DataFrame({'Col1'['Adams','Baker','Cash','Jones','Thomas'],\ 
       'Col2': ['A','B','C','D','E'],'Col3':[10,11,12,13,14]}) 
df2 = pd.DataFrame({'Col1':['Adams','Cash','Fox','Jones','Johnson'],\ 
       'Col2': ['D','E','F','G','H'],'Col3':[40,50,60,70,80]}) 
df3 = pd.DataFrame({'Col1': ['Adams','Barns','Jones','Smith','Thomas'],\ 
       'Col2':['F','G','J','L','M'],'Col3':[21,21,22,23,24]}) 
print df1 
print df2 
print df3 

,并提供:

 Col 1 Col2 Col3 
0 Adams A 10 
1 Baker B 11 
2 Cash C 12 
3 Jones D 13 
4 Thomas E 14 
    Col1 Col2 Col3 
0 Adams D 40 
1  Cash E 50 
2  Fox F 60 
3 Jones G 70 
4 Johnson H 80 
    Col1 Col2 Col3 
0 Adams F 21 
1 Barns G 21 
2 Jones J 22 
3 Smith L 23 
4 Thomas M 24 

我想结束了:

Adams A  10 
Adams D  40 
Adams F  21 
Jones D  13 
Jones G  70 
Jones J  22 

有一个简洁的方式来做到这一点?

回答

0

一个解决办法是先获取Col1中的存在于所有DataFrames的值,然后限制每个DataFrames的这些共同的价值观,然后串联受限DataFrames:

common_values = list(set(df1.Col1) & set(df2.Col1) & set(df3.Col1)) 
df = pd.concat([df1[df1.Col1.isin(common_values)], df2[df2.Col1.isin(common_values)], df3[df3.Col1.isin(common_values)]], ignore_index=True) 

这会给你以下结果:

print(df) 

    Col1 Col2 Col3 
    Adams A 10 
    Jones D 13 
    Adams D 40 
    Jones G 70 
    Adams F 21 
    Jones J 22 

我还注意到,您想要的数据帧进行排序,如果是这样的话,你可以用下面的命令对其进行排序:

df = df.sort(['Col1', 'Col2', 'Col3']) 

这会给你:

print(df) 

    Col1 Col2 Col3 
    Adams A 10 
    Adams D 40 
    Adams F 21 
    Jones D 13 
    Jones G 70 
    Jones J 22 
2

您可以先找到共同的价值观:

common = \ 
    set.intersection(set(df1.Col1), set(df2.Col1), set(df3.Col1)) 

然后串连其值设定共同的价值观中的行:

pd.concat([ 
    df1[df1.Col1.isin(common)], 
    df2[df2.Col1.isin(common)], 
    df3[df3.Col1.isin(common)]]).sort_values(by='Col1') 
0

首先,创建一个容器来容纳你的数据框(dfs)。您可以在Col1的名称集交集上使用reduce在所有数据框中查找名称。最后,您可以使用query和concat一起加入相关行。

dfs = (df1, df2, df3) 

common_names = \ 
    reduce(lambda s, df: s.intersection(set(df.Col1)), # The set intersection of names. 
      dfs[1:], # Sequence of dataframes to pass through reduce starting with second. 
      set(dfs[0].Col1)) # Seed reduce with the column of names from first dataframe. 

>>> common_names 
{'Adams', 'Jones'} 

>>> pd.concat((df.query('Col1 in @common_names') for df in dfs), ignore_index=True 
      ).sort_values('Col1') 
    Col1 Col2 Col3 
0 Adams A 10 
2 Adams D 40 
4 Adams F 21 
1 Jones D 13 
3 Jones G 70 
5 Jones J 22 

该解决方案很好地扩展,因为你只需要改变的dfs应该dataframes数量改变的内容。

P.S.重读这个问题后,我意识到你是熊猫的新手。欢迎!尽管熊猫的功能非常强大,但对于您的问题没有简单的解决方案。基本上,你想过滤你的数据框来获得一个通用名称列表。然后,您要筛选这些名称的每个数据框,并连接结果。