【问题标题】:Pandas compare 2 dataframes by specific rows in all columnsPandas 按所有列中的特定行比较 2 个数据帧
【发布时间】:2016-06-06 15:19:53
【问题描述】:

我有以下包含一些原始数字的 Pandas 数据框:

import numpy as np
import pandas as pd
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 10000)

col_raw_headers = ['07_08_19 #1','07_08_19 #2','07_08_19 #2.1','11_31_19 #1','11_31_19 #1.1','11_31_19 #1.3','12_15_20 #1','12_15_20 #2','12_15_20 #2.1','12_15_20 #2.2']
col_raw_trial_info = ['Quantity1','Quantity2','Quantity3','Quantity4','Quantity5','Quantity6','TimeStamp',np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]
cols_raw = [[1,75,9,7,-4,0.4,'07/08/2019 05:11'],[1,11,20,-17,12,0.8,'07/08/2019 10:54'],[2,0.9,17,102,56,0.6,'07/08/2019 21:04'],[1,70,4,75,0.8,0.4,'11/31/2019 11:15'],[2,60,74,41,-36,0.3,'11/31/2019 16:50'],[3,17,12,-89,30,0.1,'11/31/2019 21:33'],[1,6,34,496,-84,0.5,'12/15/2020 01:36'],[1,3,43,12,-23,0.5,'12/15/2020 07:01'],[2,5,92,17,64,0.5,'12/15/2020 11:15'],[3,7,11,62,-11,0.5,'12/15/2020 21:45']]
both_values = [[1,2,3,4,8,4,3,8,7],[6,5,3,7,3,23,27,3,11],[65,3,6,78,9,2,45,6,7],[4,3,6,8,3,5,66,32,84],[2,3,11,55,3,7,33,65,34],[22,1,6,32,5,6,4,3,898],[1,6,3,2,6,55,22,6,23],[34,37,46,918,0,37,91,12,68],[51,20,1,34,12,59,78,6,101],[12,71,34,94,1,73,46,51,21]]
processed_cols = ['c_1trial','14_1','14_2','8_1','8_2','8_3','28_1','24_1','24_2','24_3']

df_raw = pd.DataFrame(zip(*cols_raw))
df_temp = pd.DataFrame(zip(*both_values))
df_raw = pd.concat([df_raw,df_temp])
df_raw.columns=col_raw_headers
df_raw.insert(0,'Tr_id',col_raw_trial_info)
df_raw.reset_index(drop=True,inplace=True)

看起来像这样:

        Tr_id       07_08_19 #1       07_08_19 #2     07_08_19 #2.1       11_31_19 #1     11_31_19 #1.1     11_31_19 #1.3       12_15_20 #1       12_15_20 #2     12_15_20 #2.1     12_15_20 #2.2
0   Quantity1                 1                 1                 2                 1                 2                 3                 1                 1                 2                 3
1   Quantity2                75                11               0.9                70                60                17                 6                 3                 5                 7
2   Quantity3                 9                20                17                 4                74                12                34                43                92                11
3   Quantity4                 7               -17               102                75                41               -89               496                12                17                62
4   Quantity5                -4                12                56               0.8               -36                30               -84               -23                64               -11
5   Quantity6               0.4               0.8               0.6               0.4               0.3               0.1               0.5               0.5               0.5               0.5
6   TimeStamp  07/08/2019 05:11  07/08/2019 10:54  07/08/2019 21:04  11/31/2019 11:15  11/31/2019 16:50  11/31/2019 21:33  12/15/2020 01:36  12/15/2020 07:01  12/15/2020 11:15  12/15/2020 21:45
7         NaN                 1                 6                65                 4                 2                22                 1                34                51                12
8         NaN                 2                 5                 3                 3                 3                 1                 6                37                20                71
9         NaN                 3                 3                 6                 6                11                 6                 3                46                 1                34
10        NaN                 4                 7                78                 8                55                32                 2               918                34                94
11        NaN                 8                 3                 9                 3                 3                 5                 6                 0                12                 1
12        NaN                 4                23                 2                 5                 7                 6                55                37                59                73
13        NaN                 3                27                45                66                33                 4                22                91                78                46
14        NaN                 8                 3                 6                32                65                 3                 6                12                 6                51
15        NaN                 7                11                 7                84                34               898                23                68               101                21

我有这些数字的处理版本的单独数据框,其中:

  1. 上面的一些标题行已被删除,
  2. 列名已更改

这是第二个数据框:

df_processed = pd.DataFrame(zip(*both_values),columns=processed_cols)
df_processed = df_processed[[3,4,9,7,0,2,1,6,8,5]]

   8_1  8_2  24_3  24_1  c_1trial  14_2  14_1  28_1  24_2  8_3
0    4    2    12    34         1    65     6     1    51   22
1    3    3    71    37         2     3     5     6    20    1
2    6   11    34    46         3     6     3     3     1    6
3    8   55    94   918         4    78     7     2    34   32
4    3    3     1     0         8     9     3     6    12    5
5    5    7    73    37         4     2    23    55    59    6
6   66   33    46    91         3    45    27    22    78    4
7   32   65    51    12         8     6     3     6     6    3
8   84   34    21    68         7     7    11    23   101  898

每个数据帧的共同部分:

对于每一列,原始数据帧的第 8 行之后的行与处理后的数据帧的第 1 行之前的行相同。两个数据框中的列顺序不一样。

输出组合:

我希望将原始数据帧 dr_raw 的第 1-10 列中的第 8-16 行与处理后的数据帧 df_processed 进行比较。如果列相互匹配,那么我想提取df_raw 的行1-7df_processed 的列标题。

例子:

c_1trial 列中的值仅匹配07_08_19 #1 列中第 8-16 行中的值。我会 2 个步骤:(1)我想找到一些方法来确定这 2 列相互匹配,(2)如果 2 列确实相互匹配,那么在示例输出中,我想从匹配列。

这是我想要得到的输出:

    Tr_id       07_08_19 #1       07_08_19 #2     07_08_19 #2.1       11_31_19 #1     11_31_19 #1.1     11_31_19 #1.3       12_15_20 #1       12_15_20 #2     12_15_20 #2.1     12_15_20 #2.2
Quantity1                 1                 1                 2                 1                 2                 3                 1                 1                 2                 3
Quantity2                75                11               0.9                70                60                17                 6                 3                 5                 7
Quantity3                 9                20                17                 4                74                12                34                43                92                11
Proc_Name          c_1trial              14_1              14_2               8_1               8_2               8_3              28_1              24_1              24_2              24_3
Quantity4                 7               -17               102                75                41               -89               496                12                17                62
Quantity5                -4                12                56               0.8               -36                30               -84               -23                64               -11
Quantity6               0.4               0.8               0.6               0.4               0.3               0.1               0.5               0.5               0.5               0.5
TimeStamp  07/08/2019 05:11  07/08/2019 10:54  07/08/2019 21:04  11/31/2019 11:15  11/31/2019 16:50  11/31/2019 21:33  12/15/2020 01:36  12/15/2020 07:01  12/15/2020 11:15  12/15/2020 21:45

我的尝试遇到了麻烦:

print (df_raw.iloc[7:,1:] == df_processed).all(axis=1)

给予

ValueError: Can only compare identically-labeled DataFrame objects

print (df_raw.ix[7:].values == df_processed.values) #gives False

给予

False

我第二次尝试的问题是我没有选择.all(axis=1)。当我进行比较时,我想对每一列的所有行进行比较,而不仅仅是一行。

问题:

有没有办法从这 2 个数据帧中选择我上面显示的输出?

【问题讨论】:

  • 您的意思是原始数据帧中的 7 及以后(包括)吗?
  • 我的意思是第 8 行。我想你的意思是索引 7 对吧?
  • 嗯,没错。
  • 在您的输出示例中,您说您想要来自df_processed 的列标题,但我认为您发布了来自df_raw 的列标题?
  • 抱歉,实际上在示例输出中,我只显示了来自df_raw 的两个列标题,但我还包含了来自df_processed 的列名。我应该更清楚这一点。谢谢。

标签: python python-2.7 pandas dataframe


【解决方案1】:

这看起来像您正在寻找的输出吗?

原始数据框df:

        Tr_id    07_08_19  07_08_19.1  07_08_19.2    11_31_19  11_31_19.1  
0   Quantity1           1           1           2           1           2   
1   Quantity2          75          11         0.9          70          60   
2   Quantity3           9          20          17           4          74   
3   Quantity4           7         -17         102          75          41   
4   Quantity5          -4          12          56         0.8         -36   
5   Quantity6         0.4         0.8         0.6         0.4         0.3   
6   TimeStamp  07/08/2019  07/08/2019  07/08/2019  11/31/2019  11/31/2019   
7         NaN           1           6          65           4           2   
8         NaN           2           5           3           3           3   
9         NaN           3           3           6           6          11   
10        NaN           4           7          78           8          55   
11        NaN           8           3           9           3           3   
12        NaN           4          23           2           5           7   
13        NaN           3          27          45          66          33   
14        NaN           8           3           6          32          65   
15        NaN           7          11           7          84          34   

    11_31_19.2    12_15_20  12_15_20.1  12_15_20.2  12_15_20.3  
0            3           1           1           2           3  
1           17           6           3           5           7  
2           12          34          43          92          11  
3          -89         496          12          17          62  
4           30         -84         -23          64         -11  
5          0.1         0.5         0.5         0.5         0.5  
6   11/31/2019  12/15/2020  12/15/2020  12/15/2020  12/15/2020  
7           22           1          34          51          12  
8            1           6          37          20          71  
9            6           3          46           1          34  
10          32           2         918          34          94  
11           5           6           0          12           1  
12           6          55          37          59          73  
13           4          22          91          78          46  
14           3           6          12           6          51  
15         898          23          68         101          21

处理后的数据框dfp:

   8_1  8_2  24_3  24_1  c_1trial  14_2  14_1  28_1  24_2  8_3
0    4    2    12    34         1    65     6     1    51   22
1    3    3    71    37         2     3     5     6    20    1
2    6   11    34    46         3     6     3     3     1    6
3    8   55    94   918         4    78     7     2    34   32
4    3    3     1     0         8     9     3     6    12    5
5    5    7    73    37         4     2    23    55    59    6
6   66   33    46    91         3    45    27    22    78    4
7   32   65    51    12         8     6     3     6     6    3
8   84   34    21    68         7     7    11    23   101  898

代码:

df = pd.read_csv('raw_df.csv') # raw dataframe
dfp = pd.read_csv('processed_df.csv') # processed dataframe
dfr = df.drop('Tr_id', axis=1)

x = pd.DataFrame()
for col_raw in dfr.columns:
    for col_p in dfp.columns:
        if (dfr.tail(9).astype(int)[col_raw] == dfp[col_p]).all():
            series = dfr[col_raw].head(7).tolist()
            series.append(col_raw)
            x[col_p] = series

x = pd.concat([df['Tr_id'].head(7), x], axis=1)

输出:

       Tr_id    c_1trial        14_1        14_2         8_1         8_2  
0  Quantity1           1           1           2           1           2   
1  Quantity2          75          11         0.9          70          60   
2  Quantity3           9          20          17           4          74   
3  Quantity4           7         -17         102          75          41   
4  Quantity5          -4          12          56         0.8         -36   
5  Quantity6         0.4         0.8         0.6         0.4         0.3   
6  TimeStamp  07/08/2019  07/08/2019  07/08/2019  11/31/2019  11/31/2019   
7        NaN    07_08_19  07_08_19.1  07_08_19.2    11_31_19  11_31_19.1   

          8_3        28_1        24_1        24_2        24_3  
0           3           1           1           2           3  
1          17           6           3           5           7  
2          12          34          43          92          11  
3         -89         496          12          17          62  
4          30         -84         -23          64         -11  
5         0.1         0.5         0.5         0.5         0.5  
6  11/31/2019  12/15/2020  12/15/2020  12/15/2020  12/15/2020  
7  11_31_19.2    12_15_20  12_15_20.1  12_15_20.2  12_15_20.3 

我认为代码可以更简洁,但也许这样就可以了。

【讨论】:

  • 嘿,这非常非常接近。是否也可以在输出列中包含来自df_raw 的列名?例如。在您的第一列c_1trial 中,其中一行可以是07_08_19 #1 吗?其他列也是如此?
  • 我收到了ValueError: cannot convert float NaN to integer。这可能是由于 Python2.7 的特定问题造成的吗?它指向这条线:df.tail(9).astype(int)[col_raw].
  • 这是因为原始 DataFrame 有 Tr_id 列。我使用 df = df.drop('Tr_id', axis=1) 删除了它
【解决方案2】:

替代方案,使用DataFrame.isin()方法:

In [171]: df1
Out[171]:
   a  b  c
0  1  1  3
1  0  2  4
2  4  2  2
3  0  3  3
4  0  4  4

In [172]: df2
Out[172]:
   a  b  c
0  0  3  3
1  1  1  1
2  0  3  4
3  4  2  3
4  0  4  4

In [173]: common = pd.merge(df1, df2)

In [174]: common
Out[174]:
   a  b  c
0  0  3  3
1  0  4  4

In [175]: df1[df1.isin(common.to_dict('list')).all(axis=1)]
Out[175]:
   a  b  c
3  0  3  3
4  0  4  4

或者,如果您想从第一个数据集中减去第二个数据集。 IE。相当于 SQL 的 Pandas:

select col1, .., colN from tableA
minus
select col1, .., colN from tableB

在熊猫中:

In [176]: df1[~df1.isin(common.to_dict('list')).all(axis=1)]
Out[176]:
   a  b  c
0  1  1  3
1  0  2  4
2  4  2  2

【讨论】:

    【解决方案3】:

    我想出了这个使用循环。这是非常令人失望的:

    holder = []
    for randm,pp in enumerate(list(df_processed)):
        list1 = df_processed[pp].tolist()
        for car,rr in enumerate(list(df_raw)):
            list2 = df_raw.loc[7:,rr].tolist()
            if list1==list2:
                holder.append([rr,pp])
    
    df_intermediate = pd.DataFrame(holder,columns=['A','B'])
    df_c = df_raw.loc[:6,df_intermediate.iloc[:,0].tolist()]
    df_c.loc[df_c.shape[0]] = df_intermediate.iloc[:,1].tolist()
    df_c.insert(0,list(df_raw)[0],df_raw[list(df_raw)[0]])
    df_c.iloc[-1,0]='Proc_Name'
    df_c = df_c.reindex([0,1,2]+[7]+[3,4,5,6]).reset_index(drop=True)
    

    输出:

           Tr_id       11_31_19 #1     11_31_19 #1.1     12_15_20 #2.2       12_15_20 #2       07_08_19 #1     07_08_19 #2.1       07_08_19 #2       12_15_20 #1     12_15_20 #2.1     11_31_19 #1.3
    0  Quantity1                 1                 2                 3                 1                 1                 2                 1                 1                 2                 3
    1  Quantity2                70                60                 7                 3                75               0.9                11                 6                 5                17
    2  Quantity3                 4                74                11                43                 9                17                20                34                92                12
    3  Proc_Name               8_1               8_2              24_3              24_1          c_1trial              14_2              14_1              28_1              24_2               8_3
    4  Quantity4                75                41                62                12                 7               102               -17               496                17               -89
    5  Quantity5               0.8               -36               -11               -23                -4                56                12               -84                64                30
    6  Quantity6               0.4               0.3               0.5               0.5               0.4               0.6               0.8               0.5               0.5               0.1
    7  TimeStamp  11/31/2019 11:15  11/31/2019 16:50  12/15/2020 21:45  12/15/2020 07:01  07/08/2019 05:11  07/08/2019 21:04  07/08/2019 10:54  12/15/2020 01:36  12/15/2020 11:15  11/31/2019 21:33
    

    列的顺序与我要求的不同,但这是一个小问题。

    这种方法的真正问题是使用循环。 我希望使用一些内置的 Pandas 功能有更好的方法来做到这一点。如果您有更好的解决方案,发布。谢谢。

    【讨论】:

    • 这个帖子不是你想做的吗? stackoverflow.com/questions/30291032/…
    • 谢谢。我实际上尝试过 - 请参阅 OP。我收到一个错误ValueError: Can only compare identically-labeled DataFrame objects。不知何故,它拒绝比较具有不同名称的列。
    • 我认为答案已经说明要先重命名您的列。在你的情况下不可能吗?
    • 只要可以轻松更改这些名称,那么我不会有问题。在接受的答案中,列已重命名,但新列所指的是df_processed 中的哪些列似乎很清楚。我喜欢这种方法,因为我在他们两个之间建立了快速的联系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    相关资源
    最近更新 更多