【问题标题】:Append dataframes with different column names - Pandas附加具有不同列名的数据框 - 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 应用答案。如果不是,您可能想尝试模糊字符串匹配。如果您需要帮助,我可以发布答案。
  • 你有兴趣分享起泡串的方法吗?如果列的顺序不同。

标签: python python-3.x pandas python-2.7 dataframe


【解决方案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)
    
    

    【讨论】:

    • 感谢您的回答。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 2018-01-17
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    相关资源
    最近更新 更多