【问题标题】:How to tell if a value changed over dimension(s) in Pandas如何判断 Pandas 中的值是否在维度上发生了变化
【发布时间】:2017-03-22 17:57:52
【问题描述】:

假设我有一些日期的客户数据,我想看看他们的地址是否发生了变化。在那些日期。理想情况下,我想将发生更改的两列复制到一个新表中,或者只是获取总更改量的指标。

所以,如果我有一张这样的桌子

Date , Customer , Address
12/31/14, Cust1, 12 Rocky Hill Rd
12/31/15, Cust1, 12 Rocky Hill Rd
12/31/16, Cust1, 14 Rocky Hill Rd
12/31/14, Cust2, 12 Testing Rd
12/31/15, Cust2, 12 Testing Ln
12/31/16, Cust2, 12 Testing Rd

我最终会计算出两次更改,客户 1 在 12/31/15 和 12/31/16 之间的 Rocky Hill Rd 12 号之间的更改以及 Cust2 在 14 年 12 月 31 日和 2015 年 12 月 31 日之间的更改。

理想情况下我可以得到一张这样的桌子

Dates , Customer , Change
12/31/15 to 12/31/16, Cust1, 12 Rocky Hill Rd to 14 Rocky Hill Rd
12/31/14 to 12/31/15, Cust2, 12 Testing Rd to 12 Testing Ln

或者甚至只是更改的总数会很棒。有任何想法吗?理想情况下,我会有更多的日期,可能在这些日期之间进行多次更改,并且可能还有我希望检查更改的其他列。实际上,只需汇总每个列在某个日期期间对客户记录的更改就足够了。

我是 Panda 的新手,不太确定从哪里开始。

编辑: 正如我在下面的解决方案中所指出的,我希望能够传递一个更大的数据帧,而不仅仅是一个地址来检测变化。例如,我已经在 R 中完成了这一点,如下所示: `在此输入代码

`#How many changes have occured (unique values - 1)
UniLen <-  function(x){
  x <- length(unique(x))-1
  return(x)
}
#Create a vector of Address Features to check for changes in
Address_Features <- c("AddrLine1", "AddrLine2", "AddrLine3", "CityName", "State", "ZipCodeNum", "County")
#Check for changes in each address 'use this address for description' for each customer
AddressChanges_Detail <- mktData[,c("CustomerNumEID","AddressUniqueRelationDesc",Address_Features)] %>%
  group_by(CustomerNumEID, AddressUniqueRelationDesc) %>%
  summarise_each(funs(UniLen))

#Summarise results (how many changes for each feature)
AddressChanges_Summary <- AddressChanges_Detail[,Address_Features] %>%
  summarise_each(funs(sum))

这使我们可以计算发生了多少更改,但我错过了更改发生的日期以及更改功能的来源和目的...您提出的 Python 解决方案似乎可以解决这个问题使用 .shift 而不仅仅是某个组的唯一值的摘要。理想情况下,我想要两全其美:)。

【问题讨论】:

    标签: python pandas difference array-difference


    【解决方案1】:
    df
    

    输入数据帧

        Date    Customer    Address
    0   12/31/14    Cust1   12 Rocky Hill Rd
    1   12/31/15    Cust1   12 Rocky Hill Rd
    2   12/31/16    Cust1   14 Rocky Hill Rd
    3   12/31/14    Cust2   12 Testing Rd
    4   12/31/15    Cust2   12 Testing Ln
    5   12/31/16    Cust2   12 Testing Rd
    

    地址更改功能:

    def changeAdd(x):
        x=x[x.Address != x.shift(-1).Address]
        df1 = pd.DataFrame({'Date':x.shift(1).Date + ' to '+ x.Date,
                  'Customer':x.Customer.max(),
                  'Address':x.shift(1).Address +' to ' + x.Address})
        return df1[df1.Address.notnull()]
    
    
    dm = df.groupby('Customer')\
       .apply(changeAdd)\
       .reset_index(drop=True)[['Date','Customer','Address']]
    
    dm
    

    输出数据框:

    Date    Customer    Address
    0   12/31/15 to 12/31/16    Cust1   12 Rocky Hill Rd to 14 Rocky Hill Rd
    1   12/31/14 to 12/31/15    Cust2   12 Testing Rd to 12 Testing Ln
    2   12/31/15 to 12/31/16    Cust2   12 Testing Ln to 12 Testing Rd
    

    【讨论】:

    • 这似乎成功了,谢谢!我将考虑对函数进行一些参数化,以便可以更轻松地将其应用于不同的分组或列。如果我得到它,我会发布结果。
    • 嗨,斯科特,你能看到我的帖子编辑并可能提供一些额外的建议吗?对于如何最好地“参数化”您的解决方案,我有点不知所措。
    • 您到底想参数化什么?监控变化的列/列?改变的规则是什么?如果两者都改变​​或其中一个或另一个改变?等等……
    • 我的目的是为每一列独立生成指标(而不为每一列编写新函数)。我正在查看一堆与客户相关的数据(姓名、电话号码、电子邮件、地址等),我希望能够传递一个数据集,我在其中分组说一个客户 # 并查看有多少客户数据独立变化的时代。在一个理想的世界中,我能够生成一个类似于您为每个功能所做的数据集,其中我知道以前的值和新的值是什么以及以前的日期和新的日期是什么。我已经能够在 R 中使用 uniqueValuesAndSummary 做到这一点
    • def changeAdd(x,incolumn): x=x[x[incolumn] != x.shift(-1)[incolumn]] df1 = pd.DataFrame({'Date':x. shift(1).Date + ' to '+ x.Date, 'Customer':x.Customer.max(), 'Address':x.shift(1)[incolumn] +' to ' + x[incolumn]} ) 返回 df1[df1[incolumn].notnull()]
    猜你喜欢
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多