附加具有不同列名的数据框 - 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 个数据帧的列重命名为统一
请注意,实时我可能有不同列名的数据框,我可能事先不知道,但它们中的值将始终相同,属于列Ethnicity
、Gender
和Person_id
。但请注意,还有其他几列,例如Age
、Date
、bp reading
等
目前,我通过使用下面的代码手动读取列名来做到这一点
df2.columns
df2.rename(columns=ethnicity:'ethn',gender = 'gen',person_id='pers_id,
inplace=True)
如何将所有数据框的列名设置为相同(gender
、ethnicity
、person_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 数据框忽略列名