【问题标题】:Use column combinations to find data mismatch in rows pandas使用列组合查找行中的数据不匹配 pandas
【发布时间】:2019-04-23 10:17:49
【问题描述】:

根据列值的组合获取所有单元格值的最佳方法是什么?

示例数据框一:

  Stock                         Name  Price
0    AMD       Advanced Micro Devices    100
1     GE     General Electric Company    200
2    BAC  Bank of America Corporation    300
3   AAPL                   Apple Inc.    500
4   MSFT        Microsoft Corporation   1000
5  GOOGL                Alphabet Inc.   2000

示例数据框二:

  Stock                         Name  Price
0    AMD       Advanced Micro Devices    100
1     GE     General Electric Company    200
2    BAC  Branch of America Corporation  300
3   AAPL                   Apple Inc.    500
4   MSFT        Microsoft Corporation   1000
5  GOOGL                Alphabet Inc.   2000

例如:我想使用 (Stock and Name) 作为关键列,然后比较数据集。目标是打印两个数据集之间的不匹配条目,并将 Stock+Name 列用作组合键。

我正在使用 Pandas/Python3.7

样本输出:

BAC Bank of America Corporation 300 --- BAC 美国分行 公司 300

【问题讨论】:

  • DataFrames 或Stock 名称之间的股票名称是否不匹配?
  • 股票名称在数据框之间是一致的 - 但与之关联的其他列可能不同 - 我想识别。
  • @Greedy coder,那么我给出的答案适合您的解决方案,可以根据需要进行匹配。
  • 贪婪的编码员,您可以投票并标记符合您要求的已接受答案,这是将其从未回答队列中移出的方式。

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


【解决方案1】:

也许,使用 merge + query 的 FULL INNER JOIN?

df1.merge(df2, on='Stock').query('Name_x != Name_y')

  Stock                       Name_x  Price_x                         Name_y  Price_y
2   BAC  Bank of America Corporation      300  Branch of America Corporation      300

或者,与map 略有不同的解决方案,您可以使用它来获取股票代码:

m = df1.Stock.map(df2.set_index('Stock').Name).ne(df1.Name)
symbols = df1.loc[m, 'Stock']

print(symbols)
2    BAC
Name: Stock, dtype: object

然后通过股票代码访问每个DataFrame行:

df1[df1.Stock.isin(symbols)]
  Stock                         Name  Price
2   BAC  Bank of America Corporation    300

df2[df2.Stock.isin(symbols)]
  Stock                           Name  Price
2   BAC  Branch of America Corporation    300

【讨论】:

  • 可能名称相同但股票不一样?
  • @W-B 好问题,有可能,但看看这个股票数据,我不知道这是否会成为问题......将等待 OP :)
  • 名称字段可以不同/有错误/错别字——这就是我想要捕捉的。
【解决方案2】:

如果它们位于两个数据帧中,则使用.concat 将它们无条件合并非常简单。一旦他们加入,这里有一种方法来获得不匹配:

import pandas as pd

df1 = pd.DataFrame({
    "Ticker_y": list("qwerty"),
    "Name_y": list("asdfgh"),
    "Ticker_x": list("qw3r7y"),
    "Name_x": list("as6f8h")
})

mismatch = df1[(df1["Ticker_y"] != df1["Ticker_x"]) & (df1["Name_y"] != df1["Name_x"])]

最后一行只是说“只有满足这些条件的 df。”

【讨论】:

    【解决方案3】:

    我们可以使用 isin 使用值序列来测试,因为它确保 DataFrame 中的每个元素都包含在值中

    第一个数据帧

    >>> df1
       Stock                         Name  Price
    0    AMD       Advanced Micro Devices    100
    1     GE     General Electric Company    200
    2    BAC  Bank of America Corporation    300
    3   APPL                   Apple Inc.    500
    4   MSFT        Microsoft Corporation   1000
    5  GOOGL                Alphabet Inc.   2000
    

    第二个数据帧

    >>> df2
       Stock                           Name  Price
    0    AMD         Advanced Micro Devices    100
    1     GE       General Electric Company    200
    2    BAC  Branch of America Corporation    300
    3   APPL                     Apple Inc.    500
    4   MSFT          Microsoft Corporation   1000
    5  GOOGL                  Alphabet Inc.   2000
    

    你可以去..

    >>> df2[~df2.Name.isin(df1.Name.values)]
      Stock                           Name  Price
    2   BAC  Branch of America Corporation    300
    

    >>> df1[~df1.Name.isin(df2.Name.values)]
      Stock                         Name  Price
    2   BAC  Bank of America Corporation    300
    

    【讨论】:

    • 我认为这是不对的。这个想法是找到所有具有相同符号但名称不同的行。这只会找到那些在两个 DataFrame 中不常见的名称(不是同一件事)
    • 如果 Stock 在两个 DataFrame 之间命名为常量,这将起作用,我已要求 OP 澄清,因为它在 POST 中看起来很相似。
    猜你喜欢
    • 2017-12-31
    • 2022-01-24
    • 2014-04-27
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    相关资源
    最近更新 更多