【问题标题】:DataFrames are not equal after applying groupby but I can't tell why应用 groupby 后 DataFrames 不相等,但我不知道为什么
【发布时间】:2019-02-06 21:05:30
【问题描述】:

对于随后出现的代码墙和糟糕的格式,我深表歉意。当我应用 DataFrame.equals() 或更高版本的 df1 == df2 时,我尝试了尽可能多的方法来找出导致这些数据帧返回 False 的原因。我找不到他们之间的任何差异。

我通过将 groupby 应用于除 ORDER_QTY 之外的所有列上的第一个 (bdf) 来获得第二个数据帧 (dftest)。由于这两个数据帧的行数相同,我假设没有任何变化(这并不让我感到惊讶。)但是,为了确保我使用 bdf.equals(dftest) 比较它们并且它返回 false。这是在我确保列的顺序正确之后。我注意到的唯一另一件事是数据框的大小不同。否则我迷路了……

In:
dftest = bdf.groupby(['SITE', 'CUST', 'ORDER_NUMBER', 'ORDER_DATE', 'PURCHASE_ORDER', 'CHANNEL', 'SHIP_TO', 'PROD_LINE', 'GROUP_NUMBER', 'DESCRIPTION', 'ITEM', 'FW_END_DT', 'BPS_INCLUDE']).sum().reset_index()
dftest = dftest[['SITE', 'CUST', 'ORDER_NUMBER', 'ORDER_DATE', 'PURCHASE_ORDER', 'CHANNEL', 'SHIP_TO', 'PROD_LINE', 'GROUP_NUMBER', 'DESCRIPTION', 'ITEM', 'ORDER_QTY', 'FW_END_DT', 'BPS_INCLUDE']]

print(bdf.equals(dftest))
print(bdf.columns)
print(dftest.columns)


Out:
False
Index(['SITE', 'CUST', 'ORDER_NUMBER', 'ORDER_DATE', 'PURCHASE_ORDER',
       'CHANNEL', 'SHIP_TO', 'PROD_LINE', 'GROUP_NUMBER', 'DESCRIPTION',
       'ITEM', 'ORDER_QTY', 'FW_END_DT', 'BPS_INCLUDE'],
      dtype='object')
Index(['SITE', 'CUST', 'ORDER_NUMBER', 'ORDER_DATE', 'PURCHASE_ORDER',
       'CHANNEL', 'SHIP_TO', 'PROD_LINE', 'GROUP_NUMBER', 'DESCRIPTION',
       'ITEM', 'ORDER_QTY', 'FW_END_DT', 'BPS_INCLUDE'],
      dtype='object')

^Columns 似乎相同,但 bdf.equals(dftest) 产生 False

In:
bdf.info()
dftest.info()


Out:
<class 'pandas.core.frame.DataFrame'>
Index: 53025 entries, 0 to 53024
Data columns (total 14 columns):
SITE              53025 non-null object
CUST              53025 non-null object
ORDER_NUMBER      53025 non-null object
ORDER_DATE        53025 non-null datetime64[ns]
PURCHASE_ORDER    53025 non-null object
CHANNEL           53025 non-null object
SHIP_TO           53025 non-null object
PROD_LINE         53025 non-null object
GROUP_NUMBER      53025 non-null object
DESCRIPTION       53025 non-null object
ITEM              53025 non-null object
ORDER_QTY         53025 non-null int64
FW_END_DT     53025 non-null datetime64[ns]
BPS_INCLUDE       53025 non-null int64
dtypes: datetime64[ns](2), int64(2), object(10)
memory usage: 6.1+ MB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 53025 entries, 0 to 53024
Data columns (total 14 columns):
SITE              53025 non-null object
CUST              53025 non-null object
ORDER_NUMBER      53025 non-null object
ORDER_DATE        53025 non-null datetime64[ns]
PURCHASE_ORDER    53025 non-null object
CHANNEL           53025 non-null object
SHIP_TO           53025 non-null object
PROD_LINE         53025 non-null object
GROUP_NUMBER      53025 non-null object
DESCRIPTION       53025 non-null object
ITEM              53025 non-null object
ORDER_QTY         53025 non-null int64
FW_END_DT     53025 non-null datetime64[ns]
BPS_INCLUDE       53025 non-null int64
dtypes: datetime64[ns](2), int64(2), object(10)
memory usage: 5.7+ MB

^正如我提到的,除了大小之外,所有东西看起来都一样。

In:
common = bdf.merge(dftest,on=['SITE', 'CUST', 'ORDER_NUMBER', 'ORDER_DATE', 'PURCHASE_ORDER', 'CHANNEL', 'SHIP_TO', 'PROD_LINE', 'GROUP_NUMBER', 'DESCRIPTION', 'ITEM', 'ORDER_QTY', 'FW_END_DT', 'BPS_INCLUDE'], how='outer', indicator=True)
print(common[common['_merge'] != 'both'])



Out:
Empty DataFrame
Columns: [SITE, CUST, ORDER_NUMBER, ORDER_DATE, PURCHASE_ORDER, CHANNEL, SHIP_TO, PROD_LINE, GROUP_NUMBER, DESCRIPTION, ITEM, ORDER_QTY, FW_END_DT, BPS_INCLUDE, _merge]
Index: []

尝试合并和选择不在两个 df 中的行

In:
bdf[(~bdf.SITE.isin(common.SITE))&(~bdf.CUST.isin(common.CUST))&(~bdf.ORDER_NUMBER.isin(common.ORDER_NUMBER))&(~bdf.ORDER_DATE.isin(common.ORDER_DATE))&(~bdf.PURCHASE_ORDER.isin(common.PURCHASE_ORDER))&(~bdf.CHANNEL.isin(common.CHANNEL))&(~bdf.SHIP_TO.isin(common.SHIP_TO))&(~bdf.PROD_LINE.isin(common.PROD_LINE))&(~bdf.GROUP_NUMBER.isin(common.GROUP_NUMBER))&(~bdf.DESCRIPTION.isin(common.DESCRIPTION))&(~bdf.ITEM.isin(common.ITEM))&(~bdf.ORDER_QTY.isin(common.ORDER_QTY))&(~bdf.FW_END_DT.isin(common.FW_END_DT))&(~bdf.BPS_INCLUDE.isin(common.BPS_INCLUDE))]



Out:
SITE    CUST    ORDER_NUMBER    ORDER_DATE  PURCHASE_ORDER  CHANNEL SHIP_TO PROD_LINE   GROUP_NUMBER    DESCRIPTION ITEM    ORDER_QTY   FW_END_DT   BPS_INCLUDE

什么都不做

In:
(bdf == dftest).all().all()




Out:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-34-6c2f52f55e60> in <module>()
----> 1 (bdf == dftest).all().all()

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\ops.py in f(self, other)
   1611             # Another DataFrame
   1612             if not self._indexed_same(other):
-> 1613                 raise ValueError('Can only compare identically-labeled '
   1614                                  'DataFrame objects')
   1615             return self._compare_frame(other, func, str_rep)

ValueError: Can only compare identically-labeled DataFrame objects

它们的标签不一样?

当我尝试搜索以下内容时,有人建议我尝试:

In:
bdf.eq(dftest)


Out:
    SITE    CUST    ORDER_NUMBER    ORDER_DATE  PURCHASE_ORDER  CHANNEL SHIP_TO PROD_LINE   GROUP_NUMBER    DESCRIPTION ITEM    ORDER_QTY   FW_END_DT   BPS_INCLUDE
0   False   False   False   False   False   False   False   False   False   False   False   False   False   False
1   False   False   False   False   False   False   False   False   False   False   False   False   False   False
2   False   False   False   False   False   False   False   False   False   False   False   False   False   False
3   False   False   False   False   False   False   False   False   False   False   False   False   False   False
4   False   False   False   False   False   False   False   False   False   False   False   False   False   False
5   False   False   False   False   False   False   False   False   False   False   False   False   False   False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
52995   False   False   False   False   False   False   False   False   False   False   False   False   False   False
106050 rows × 14 columns

在这种情况下,看起来每对单元格都不匹配...... :(

我是否遗漏了一些非常明显的东西?

【问题讨论】:

  • (bdf.index == dftest.index).all() 打印什么?如果是False,那么问题是索引不一样,所以你可以尝试bdf.index = dftest.index再试一次。
  • 它最初给了我一个错误。在我尝试 bdf.index = dftest.index 之后,它打印了 False。
  • (bdf.index == dftest.index).all() 出错了?那是什么?
  • 对不起,我的错误。它最初打印的是 False。
  • 好吧,那不是好消息吗?这意味着比较不起作用,因为索引不一样。

标签: python pandas dataframe


【解决方案1】:

您的数据中是否有任何 nan / null / 缺失值?

如果是这样 groupby.sum() 可以用例如替换这些值0. 在数字 dtypes 的情况下

如果以上是罪魁祸首, groupby.first() 结果将与您的原始输入相同

【讨论】:

  • 我没有任何空值。
猜你喜欢
  • 2019-10-16
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多