Python 如何读取合并结果?

Python 如何读取合并结果?,python,pandas,join,dataframe,merge,Python,Pandas,Join,Dataframe,Merge,使用pandas merge,结果列令人困惑: df1 = pd.DataFrame(np.random.randint(0, 100, size=(5, 5))) df2 = pd.DataFrame(np.random.randint(0, 100, size=(5, 5))) df2[0] = df1[0] # matching key on the first column. # Now the weird part. pd.merge(df1, df2, left_on=0,

使用pandas merge,结果列令人困惑:

df1 = pd.DataFrame(np.random.randint(0, 100, size=(5, 5)))

df2 = pd.DataFrame(np.random.randint(0, 100, size=(5, 5)))

df2[0] = df1[0]  # matching key on the first column.

# Now the weird part.
pd.merge(df1, df2, left_on=0, right_on=0).shape
Out[96]: (5, 9)
pd.merge(df1, df2, left_index=True, right_index=True).shape
Out[102]: (5, 10)
pd.merge(df1, df2, left_on=0, right_on=1).shape
Out[107]: (0, 11)
列的数量不固定,列标签也不稳定,更糟糕的是,这些都没有明确的记录

我想读取结果数据帧的一些列,这些列有许多列(数百列)。目前我正在使用.iloc[],因为标记工作太多了。但我担心由于奇怪的合并结果,这很容易出错。 读取合并数据框中某些列的正确方法是什么


Python:2.7.13,Pandas:0.19.2

合并键

1.1当连接键是一列时,在键上合并(这是适合您的解决方案,您可以说“df2[0]=df1[0]”匹配第一列上的键。 ))

1.2当合并键为索引时,在索引上合并 ==>在第二次合并(pd.merge(df1,df2,left\u index=True,right\u index=True).shape)中多得到1列的原因是,初始连接键现在出现两次“0\u x”和“0\u y”

关于列名

列名在合并期间不会更改,除非两个数据帧中有同名的列。列的更改如下所示,您将得到:

  • “初始列名称”+“\ux”(后缀“\ux”添加到左侧数据帧(df1)的列中)

  • 'initial_column_name'+''u y'(后缀''u y'添加到右侧数据帧(df2)的列中)


为了处理合并结果中列数的3种不同情况,我最后检查了列数,然后将列数索引转换为在.iloc[]中使用。这是代码,供将来的搜索者使用

这仍然是我现在知道的处理大量专栏的最好方法。如果有更好的答案,我会标出来

转换列号索引的实用方法:

def get_merged_column_index(num_col_df, num_col_df1, num_col_df2, col_df1=[], col_df2=[], joinkey_df1=[], joinkey_df2=[]):
    """Transform the column indexes in old source dataframes to column indexes in merged dataframe. Check for different pandas merged result formats.

    :param num_col_df: number of columns in merged dataframe df.
    :param num_col_df1: number of columns in df1.
    :param num_col_df2: number of columns in df2.
    :param col_df1: (list of int) column position in df1 to keep (0-based).
    :param col_df2: (list of int) column position in df2 to keep (0-based).
    :param joinkey_df1:  (list of int) column position (0-based). Not implemented now.
    :param joinkey_df2:  (list of int) column position (0-based). Not implemented now.
    :return: (list of int) transformed column indexes, 0-based, in merged dataframe.
    """

    col_df1 = np.array(col_df1)
    col_df2 = np.array(col_df2)

    if num_col_df == num_col_df1 + num_col_df2: # merging keeps same old columns
        col_df2 += num_col_df1
    elif num_col_df == num_col_df1 + num_col_df2 + 1: # merging add column 'key_0' to the head
        col_df1 += 1
        col_df2 += num_col_df1 + 1
    elif num_col_df <= num_col_df1 + num_col_df2 - 1: # merging deletes (possibly many) duplicated "join-key" columns in df2, keep and do not change order columns in df1.
        raise ValueError('Format of merged result is too complicated.')
    else:
        raise ValueError('Undefined format of merged result.')

    return np.concatenate((col_df1, col_df2)).astype(int).tolist()

如果在
df1
df2
中合并具有相同名称的数据帧,则会添加后缀。所以,如果第一列合并得到4个相同的列(连接列相同),那么输出是
9
columns。在第二次按索引合并时,输出为10列。最后按不同列合并(默认内部联接),因此有时返回一些数据,有时不返回任何数据(因为随机数据)。如果列名称不同,数据帧的形状不同,则很难找到便于选择的通用解决方案。@jezrael:那么在具有相同标签的两列上合并将删除一列?合并两个不同标签的列将添加1个“key_0”列?如果我不管理列的标签怎么办?@jezrael:事实证明,在某些情况下,将两列合并为不同的标签不会添加列“key\u 0”。这一机制让人非常困惑。我不会对你的第一个问题投反对票——不删除,它只创建一个连接的列——使用df1获取值,然后使用
df2
创建两个数据帧中的值的列。我注意到更改的列标签,但问题是在一些合并之后,标签会弄乱。此外,正如我所说的,列的数量很大,所以我使用iloc[]来获取数据。我仍然不清楚哪些列将被删除或添加,以及规则是什么。如何从合并的数据帧中获取,比如说df1的第1列和df2的第(3,4)列?我想到的一个可能的解决方案是检查合并的数据帧的形状,然后在三种情况下进行处理。但是有没有更好的方法来遵循熊猫文档?1:不会删除任何列。添加到数据帧的唯一列是与之合并的数据帧的列。连接键也不会重复。关于选择列:pd.merge(df1[['join\u key','column\u 1']],df2['join\u key','column\u 1','column\u 2','column\u 3,left\u on='join\u key',right\u on='join\u key)=>结果:包含列['join\u key','column\u 1\u x','column\u 1\u y','column\u 2','column\u 3]的数据帧
cols_toextract_df1 = []
cols_toextract_df2 = []
converted_cols = get_merged_column_index(num_col_df=df.shape[1], num_col_df1=df1.shape[1], num_col_df2=df2.shape[1], col_df1=cols_toextract_df1, col_df2=cols_toextract_df1)
extracted_df = df.iloc[:, converted_cols]