【问题标题】:how to handle different spelling of column names when extracting data?提取数据时如何处理列名的不同拼写?
【发布时间】:2020-02-27 19:09:01
【问题描述】:

对于这个例子,我有 2 个数据帧,df1 中的流派列是第 3 列,但在 df2 中它是第 2 列,标题也略有不同。在我的实际脚本中,我必须搜索列名,因为列位置在它读取的每张表中都不同。

我如何将不同的标题名称识别为同一事物?

df1 = pd.DataFrame({'TITLE': ['The Matrix','Die Hard','Kill Bill'],
               'VENDOR ID': ['1234','4321','4132'],
               'GENRE(S)': ['Action', 'Adventure', 'Drama']})

df2 = pd.DataFrame({'TITLE': ['Toy Story','Shrek','Frozen'],
               'Genre': ['Animation', 'Adventure', 'Family'],
               'VENDOR ID': ['5678','8765','8576']})

column_names = ['TITLE','VENDOR ID','GENRE(S)']

appended_data = []

sheet1 = df1[df1.columns.intersection(column_names)]
appended_data.append(sheet1)
sheet2 = df2[df2.columns.intersection(column_names)]
appended_data.append(sheet2)

appended_data = pd.concat(appended_data, sort=False)

output:

        TITLE VENDOR ID   GENRE(S)
0  The Matrix      1234     Action
1    Die Hard      4321  Adventure
2   Kill Bill      4132      Drama
0   Toy Story      5678        NaN
1       Shrek      8765        NaN
2      Frozen      8576        NaN

desired output:

        TITLE VENDOR ID   GENRE(S)
0  The Matrix      1234     Action
1    Die Hard      4321  Adventure
2   Kill Bill      4132      Drama
0   Toy Story      5678  Animation
1       Shrek      8765  Adventure
2      Frozen      8576     Family

【问题讨论】:

  • 您需要向我们提供您作为输出获得的表格以及您希望它看起来像的表格。 Read 关于最少且可重复的问题。
  • 我无法显示输出,因为它包含我无法共享的数据。但是,我得到的输出是一个以 column_names 作为标题的电子表格。问题是,例如,“GENRE(S)”列将包含从具有名为“GENRES(S)”的列的源工作表中提取的数据,但是当工作表具有名为“Genre”的列时 - 单元格为空,因为该列名不匹配。另一个问题是源表中的列顺序不同,这就是我搜索列名而不是列索引的原因。
  • 一张图片胜过千言万语。您必须创建输入和预期输出的 DUMMY 数据,而不是对其进行描述。
  • 在帖子中添加了示例。如果我不能指定列名或它们的索引号,是否仍然可以提取数据?
  • 这是不可重现的。你读过How to make good reproducible pandas examples吗?请阅读该内容,然后以可重复的形式编辑您的问题。

标签: python excel pandas extract


【解决方案1】:

感谢您抽出宝贵时间来做这件事。提出一个好的问题非常重要,既然您提出了一个连贯的问题,我就能很快找到一个简单的解决方案:

import pandas as pd

df1 = pd.DataFrame({'TITLE': ['The Matrix','Die Hard','Kill Bill'],
                'VENDOR ID': ['1234','4321','4132'],
                 'GENRE(S)': ['Action', 'Adventure', 'Drama']})

df2 = pd.DataFrame({'TITLE': ['Toy Story','Shrek','Frozen'],
                    'Genre': ['Animation', 'Adventure', 'Family'],
                'VENDOR ID': ['5678','8765','8576']})

简单的方法:
我们将在下面使用.append(),但要使其工作,我们需要df1df2 中的列进行匹配。在这种情况下,我们只需将 df2's 'Genre' 替换为 'GENRE(S)'

df2.columns = ['TITLE', 'GENRE(S)', 'VENDOR ID']

df3 = df1.append(df2)
print(df3)

    GENRE(S)       TITLE VENDOR ID
0     Action  The Matrix      1234
1  Adventure    Die Hard      4321
2      Drama   Kill Bill      4132
0  Animation   Toy Story      5678
1  Adventure       Shrek      8765
2     Family      Frozen      8576

更详细:
现在,对于单个用例,这是可行的,但可能存在许多不匹配的列和/或必须重复执行此操作的情况。这是一个解决方案,使用布尔索引查找不匹配的名称,然后使用 zip().rename() 映射列名称:

# RELOAD YOUR ORIGINAL DF'S 

df1_find = df1.columns[~df1.columns.isin(df2.columns)] # select col name that isnt in df2
df2_find = df2.columns[~df2.columns.isin(df1.columns)] # select col name that isnt in df1

zipped = dict(zip(df2_find, df1_find)) # df2_find as key, df1_find as value

df2.rename(columns=zipped, inplace=True) # map zipped dict to the column names

df3 = df1.append(df2)
print(df3)

    GENRE(S)       TITLE VENDOR ID
0     Action  The Matrix      1234
1  Adventure    Die Hard      4321
2      Drama   Kill Bill      4132
0  Animation   Toy Story      5678
1  Adventure       Shrek      8765
2     Family      Frozen      8576

记住:

  1. 这种做法假定您的两个 df 具有相同的计数 列数
  2. 这还假设df1 具有您理想的列名 将使用其他 dfs 来修复他们的列名

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 2020-07-01
    • 2013-09-17
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多