python中数据框同时加两列_关于pandas:Python-比较数据框中的两列

我有两个文件,两者之间有微小差异。我想输出不同的值,以便可以看到更改的内容。有很多要比较的列。

这是示例数据(示例中唯一的区别是第一行的状态):

数据1

ID      PROGRAM_CODE    Status

123     888             Active

123     777             Active

345     777             Inactive

345     999             Active

678     666             Inactive

901     777             Inactive

901     888             Active

数据2

ID      PROGRAM_CODE    Status

123     888             BLAH

123     777             Active

345     777             Inactive

345     999             Active

678     666             Inactive

901     777             Inactive

901     888             Active

所需输出:

ID      Status_1    Status_2

123     Active      Inactive

我当前的方法是创建列列表,合并两个数据框,然后在for循环中使用列列表进行比较。我相信我的代码会比较系列并输出整个系列(如果有任何区别的话)。我只想查看具有不同值的一行。此外,如果一个字段具有值,而另一字段中为空白,则此方法不起作用。

码:

import pandas as pd

df1 = pd.read_excel(r"P:\data_files\data1.xlsx")

df2 = pd.read_excel(r"P:\data_files\data2.xlsx")

# create list of columns

l1 = list(df1)

# dropping the join values from the list because I don't want to compare those

l1 = [e for e in l1 if e not in ('ID','PROGRAM_CODE')]

# merge dataframes

df3 = df1.merge(df2, how='outer', on=['ID','PROGRAM_CODE'], suffixes=['_1', '_2'])

for x in l1:

if df3[x+'_1'].any() != df3[x+'_2'].any():

print(df3[['ID', x+'_1',x+'_2']])

上面代码的输出:

即使只有第一行的数据框之间的值不同,也会显示"状态"列的所有值。

ID      Status_1    Status_2

123     Active      Blah

123     Active      Active

345     Inactive    Inactive

345     Active      Active

678     Inactive    Inactive

901     Inactive    Inactive

901     Active      Active

编辑17/12/12

下面来自Wen的示例似乎适用于一列,但是我需要比较ID和Program_Code相同的两个文件的每一行和每一列。

我尝试了以下循环:

for x in l1:

print(df3.groupby('STUDENT_CID').x.apply(list).apply(pd.Series).add_prefix(x+'_'))

但我收到以下错误:

AttributeError: 'DataFrameGroupBy' object has no attribute 'x'

我需要一种遍历每一列的方式(两个文件都包含相同的列)。

附加示例:

数据文件1

ID      PROGRAM_CODE    I_CODE  INSTITUTION TERM    TYPE    STATUS      Hire_Date

123     888             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

123     777             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

345     777             125     GUB         Fall    FINAL   Inactive    2/3/2017 0:00

345     999             125     GUB         Fall    FINAL   Inactive    2/3/2017 0:00

678     999             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

678     888             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

901     888             654     YUI         Fall    FINAL   Inactive    5/1/2017 0:00

901     777             654     YUI         Fall    FINAL   Inactive    5/1/2017 0:00

数据文件2

ID      PROGRAM_CODE    I_CODE  INSTITUTION TERM    TYPE    STATUS      Hire_Date

123     888             111     ZBD         Fall    FINAL   Inactive    1/1/2017 0:00

123     777             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

345     777             111     ZBD         Fall    FINAL   Inactive    2/3/2017 0:00

345     999             111     ZBD         Fall    FINAL   Inactive    2/3/2017 0:00

678     999             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

678     888             111     ZBD         Fall    FINAL   Active      1/1/2017 0:00

901     888             654     YUI         Fall    FINAL   Inactive    5/1/2017 0:00

901     777             654     YUI         Fall    FINAL   Inactive    5/1/2017 0:00

期望的输出

ID  STATUS_1        STATUS_2

123 Active          Inactive

ID  INSTITUTION_1   INSTITUTION_2

345 125             111

我们使用pd.concat + drop_duplicates

df1=pd.concat([df1,df2]).drop_duplicates(keep=False)

df1

Out[1085]:

ID  PROGRAM_CODE  Status

0  123           888  Active

0  123           888    BLAH

然后我们groupby创建您需要的表

df1.groupby('ID').Status.apply(list).apply(pd.Series).add_prefix('Status_')

Out[1094]:

Status_0 Status_1

ID

123   Active     BLAH

更新

df=pd.concat([df1,df2]).drop_duplicates(keep=False)

dd=df.groupby('ID').agg(lambda x:sorted(set(x), key=list(x).index)).stack()

dd[dd.apply(len)>1]

Out[1194]:

ID

123  STATUS          [Active, Inactive]

345  PROGRAM_CODE            [777, 999]

I_CODE                  [125, 111]

INSTITUTION             [GUB, ZBD]

我如何将groupby应用于大量的列? 仅以状态为例,我有一百多个列可供比较。

它基本上类似于示例,但具有更多列,例如修改日期,citizenship_code等。其中包含日期,ID号,各种长度的字符串等。

@Dread是否需要找到所有不同的地方? 抱歉,您可以编一个小样本,然后向我展示预期的结果吗?

我添加了另一个示例,其中状态和I_Code在第二个文件中更改。 感谢您的帮助,如果我不清楚,则对不起。

我确定有更好的方法来执行此操作,但是您是否尝试过合并数据框(如您现有的那样),创建一个比较Status_1和Status_2的新列,然后删除匹配项为True的任何行? 如果您之后删除了"它们是否匹配"列,我相信您会获得理想的输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值