用不同的列名Pandas追加数据帧

2024-05-15 12:07:48 发布

您现在位置:Python中文网/ 问答频道 /正文

可以从下面的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数据帧中

当我使用下面的代码尝试此操作时,输出并不像预期的那样

^{pr2}$

enter image description here

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

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

请注意,在实时情况下,我可能有不同的列名的dataframe,这些列名我可能事先不知道,但它们中的值始终属于属于列EthnicityGender和{}。但是请注意,还有其他一些列,比如AgeDatebp reading

目前,我使用以下代码手动读取列名

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

如何将所有dataframe的列名设置为相同(genderethnicityperson_id等),而不考虑它们的原始列值


Tags: 数据代码iddataframenotgendermalefemale
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)

根据^{} documentation,您可以创建映射:

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

现在,您清楚地指出您必须执行这个运行时。如果知道列的数量和它们各自的位置不会改变,那么可以使用df2.columns()来收集实际的列名,这应该会输出如下内容:

^{pr2}$

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

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)

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html所述,您可以将多个列名一起传递,这些列名可以指向您想要的同一个最终列名。所以,最好的方法是收集所有列名,然后根据某种算法将它们映射到您需要的公共名称,或者手动执行rename命令。在

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

相关问题 更多 >