附加具有不同列名的数据框 - Pandas

Posted

技术标签:

【中文标题】附加具有不同列名的数据框 - Pandas【英文标题】:Append dataframes with different column names - Pandas 【发布时间】:2019-12-06 14:56:57 【问题描述】:

我有 3 个数据帧,可以从下面显示的代码生成

df1= pd.DataFrame('person_id':[1,2,3],'gender': ['Male','Female','Not disclosed'],'ethn': ['Chinese','Indian','European'])
df2= pd.DataFrame('pers_id':[4,5,6],'gen': ['Male','Female','Not disclosed'],'ethnicity': ['Chinese','Indian','European'])
df3= pd.DataFrame('son_id':[7,8,9],'sex': ['Male','Female','Not disclosed'],'ethnici': ['Chinese','Indian','European'])

我想做两件事

a) 将所有这 3 个数据帧附加到一个大的 result 数据帧中

当我使用以下代码尝试此操作时,输出与预期不符

df1.append(df2)

所以,为了解决这个问题,我知道我们必须重命名导致下面目标 b 的列名

b) 以优雅的方式将这 n 个数据帧的列重命名为统一

请注意,实时我可能有不同列名的数据框,我可能事先不知道,但它们中的值将始终相同,属于列EthnicityGenderPerson_id。但请注意,还有其他几列,例如AgeDatebp reading

目前,我通过使用下面的代码手动读取列名来做到这一点

df2.columns
df2.rename(columns=ethnicity:'ethn',gender = 'gen',person_id='pers_id, 
             inplace=True)

如何将所有数据框的列名设置为相同(genderethnicityperson_id 等),而不管它们的原始列值如何

【问题讨论】:

您想将 3 个不同标头的数据框合并为一个合并在相同标头下的数据框吗?您的数据是否一致,person_id 始终出现在第一列,gender 出现在第二列等等? 不,它们是随机排列的 @BerkayÖz - 可能是这样,我可以尝试解决这个问题。让我们考虑它的顺序相同 如果它们的顺序相同,您可以通过Alessandro Flati 应用答案。如果不是,您可能想尝试模糊字符串匹配。如果您需要帮助,我可以发布答案。 你有兴趣分享起泡串的方法吗?如果列的顺序不同。 【参考方案1】:

正如https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html 中提到的,您可以一起传递多个列名,这些列名可以指向您想要的相同的最终列名。因此,最好的方法是收集所有列名,然后根据某种算法或手动将它们映射到您需要的常用名称,然后运行重命名命令。

该算法可以使用名称中的相似性(使用 TF-IDF)或这些列的值中的相似性。

【讨论】:

【参考方案2】:

根据pandas documentation,您可以创建映射:

df2.rename(columns=column1:'ethn', column2:'gen', column3:'pers_id', inplace=True)

现在,您明确表示您必须执行此运行时。如果您知道列数和它们各自的位置不会改变,您可以使用df2.columns() 收集实际的列名,应该会输出如下内容:

['ethnicity', 'gender', 'person_id']

此时,您可以将映射创建为:

final_columns = ['ethn', 'gen', 'pers_id']
previous_columns = df2.columns()
mapping = previous_columns[i]: final_columns[i] for i in range(3)  # 3 is arbitrary.

然后调用

df2.rename(mapping, inplace=True)

【讨论】:

这里可以复制吗?我的意思是说,我创建了一个空数据框(df_final),其中包含我感兴趣的列名(性别、种族、Person_id)。我的数据(df_1)包含不同的列名,但顺序相同。那么我是否能够通过排除列名将数据单独复制到新的数据场? 对不起,之前的评论有误,所以我要删除它。您的策略是相同的,只需将新重命名的数据框(根据答案)附加到最后一个(必须共享相同的列名,例如final_columns【参考方案3】:

如果您不知道列的顺序,您可以尝试模糊匹配方法。模糊匹配将为您提供从 0 到 100 的 相似度/似然度 值。因此您可以确定相似度阈值,然后替换与所需列名相似的列。这是我的方法:

import pandas as pd
from fuzzywuzzy import process


df1= pd.DataFrame('person_id':[1,2,3],'gender': ['Male','Female','Not disclosed'],'ethn': ['Chinese','Indian','European'])
df2= pd.DataFrame('pers_id':[4,5,6],'gen': ['Male','Female','Not disclosed'],'ethnicity': ['Chinese','Indian','European'])
df3= pd.DataFrame('son_id':[7,8,9],'sex': ['Male','Female','Not disclosed'],'ethnici': ['Chinese','Indian','European'])

dataFrames = [df1, df2, df3]

for dataFrame in dataFrames:
  for i, column in enumerate(list(dataFrame.columns)):
    if dataFrame.columns[i] == "sex":
      dataFrame.rename(columns= dataFrame.columns[i]: "gender" , inplace = True)

colsToFix = ["person_id", "gender", "ethnicity"]
replaceThreshold = 75


ratiosPerDf = list()

for i, dataFrame in enumerate(dataFrames):
  ratioDict = dict()
  for column in colsToFix:
    ratios = process.extract(column, list(dataFrame.columns))
    ratioDict[column] = ratios
  ratiosPerDf.append(ratioDict)

for i, dfRatio in enumerate(ratiosPerDf):
  for column in colsToFix:
    bestMatching = ("", 0)
    for item in dfRatio[column]:
        if item[1] >= replaceThreshold and item[1] > bestMatching[1]:
          bestMatching = item
    if not bestMatching[1] < replaceThreshold:
      print("Column :  Best matching : ".format(column, bestMatching[0]))
      dataFrames[i].rename(columns= bestMatching[0] : column  , inplace = True)

【讨论】:

感谢您的回答。非常感谢

以上是关于附加具有不同列名的数据框 - Pandas的主要内容,如果未能解决你的问题,请参考以下文章

附加两个具有相同列、不同顺序的数据框

在循环中将字典附加到熊猫数据框

使用 pandas 连接两个数据框中的不同列(并附加相似的列)

Python Pandas - 具有不同列的 Concat 数据框忽略列名

尝试使用 pandas 数据框将数据附加到 BigQuery 表时出错

java - 如何在java中组合(连接)具有相同列名的两个数据框